ES2016 新特性:求幂运算符(**)

ES2017 新特性:Async Functions (异步函数)


概述

async(异步) 函数变体

以下是已经存在的异步函数变体。请注意无处不在的 async 关键字。

  • 异步函数声明: async function foo() {}
  • 异步函数表达式: const foo = async function () {};
  • 异步函数定义:let obj = { async foo() {} }
  • 异步箭头函数: const foo = async () => {};

async(异步) 函数总是返回 Promises

async(异步) 函数的 Promise 完成状态:

JavaScript 代码:
  1. async function asyncFunc() {
  2. return 123;
  3. }
  4. asyncFunc()
  5. .then(x => console.log(x));
  6. // 123

async(异步) 函数的 Promise 拒绝状态:

JavaScript 代码:
  1. async function asyncFunc() {
  2. throw new Error('Problem!');
  3. }
  4. asyncFunc()
  5. .catch(err => console.log(err));
  6. // Error: Problem!

通过 await 处理 async(异步) 计算的结果和错误

await(只允许在 async(异步) 函数内部使用)等待其操作对象 Promise 返回:

  • 如果 Promise 是完成状态,await 的结果是完成态的值。
  • 如果 Promise 是拒绝状态,await 会抛出拒绝值。

处理单个 async(异步) 返回值:

JavaScript 代码:
  1. async function asyncFunc() {
  2. const result = await otherAsyncFunc();
  3. console.log(result);
  4. }
  5. // 等价于:
  6. function asyncFunc() {
  7. return otherAsyncFunc()
  8. .then(result => {
  9. console.log(result);
  10. });
  11. }

按顺序处理多个 async(异步) 返回值:

JavaScript 代码:
  1. async function asyncFunc() {
  2. const result1 = await otherAsyncFunc1();
  3. console.log(result1);
  4. const result2 = await otherAsyncFunc2();
  5. console.log(result2);
  6. }
  7. // 等价于:
  8. function asyncFunc() {
  9. return otherAsyncFunc1()
  10. .then(result1 => {
  11. console.log(result1);
  12. return otherAsyncFunc2();
  13. })
  14. .then(result2 => {
  15. console.log(result2);
  16. });
  17. }

并行处理多个 async(异步) 返回值:

JavaScript 代码:
  1. async function asyncFunc() {
  2. const [result1, result2] = await Promise.all([
  3. otherAsyncFunc1(),
  4. otherAsyncFunc2(),
  5. ]);
  6. console.log(result1, result2);
  7. }
  8. // 等价于:
  9. function asyncFunc() {
  10. return Promise.all([
  11. otherAsyncFunc1(),
  12. otherAsyncFunc2(),
  13. ])
  14. .then([result1, result2] => {
  15. console.log(result1, result2);
  16. });
  17. }

错误处理:

JavaScript 代码:
  1. async function asyncFunc() {
  2. try {
  3. await otherAsyncFunc();
  4. } catch (err) {
  5. console.error(err);
  6. }
  7. }
  8. // 等价于:
  9. function asyncFunc() {
  10. return otherAsyncFunc()
  11. .catch(err => {
  12. console.error(err);博银财富

理解 async(异步) 函数

在我解释 async(异步) 函数之前,我需要解释一下如何组合使用 Promises 和 Generator ,通过看起来同步的代码来执行 async(异步) 操作。

对于能够 async(异步) 计算其一次性结果的函数,作为 ES6 一部分的 Promises 已经变得流行起来。一个例子是 客户端 fetch API ,它是 XMLHttpRequest 获取数据的替代方法。使用示例如下:

JavaScript 代码:
  1. function fetchJson(url) {
  2. return fetch(url)
  3. .then(request => request.text())
  4. .then(text => {
  5. return JSON.parse(text);
  6. })
  7. .catch(error => {
  8. console.log(`ERROR: ${error.stack}`);
  9. });
  10. }
  11. fetchJson('http://example.com/some_file.json')
  12. .then(obj => console.log(obj));

通过 generator 来编写异步代码

co 是一个使用 Promise 和 generator 来实现看似同步编码的库,但与上一示例中使用的样式相同:

JavaScript 代码:
  1. const fetchJson = co.wrap(function* (url) {
  2. try {
  3. let request = yield fetch(url);
  4. let text = yield request.text();
  5. return JSON.parse(text);
  6. }
  7. catch (error) {
  8. console.log(`ERROR: ${error.stack}`);
  9. }
  10. });

每次回调函数( generator 函数)产生一个 Promise 对象给 co ,回调会被暂停,只有当 Promise 执行完成后,co 才会继续执行回调 。 如果 Promise 处于完成状态,yield 返回完成状态的值,如果处于拒绝状态,yield 抛出拒绝状态的错误。此外,co 保证结果是通过回调执行完成才返回的(类似于 then() 所做的工作)。

通过 async(异步) 函数来编写异步代码

async(异步) 函数用的特定语法基本上和 co 类似:

JavaScript 代码:
  1. async function fetchJson(url) {
  2. try {
  3. let request = await fetch(url);
  4. let text = await request.text();
  5. return JSON.parse(text);
  6. }
  7. catch (error) {
  8. console.log(`ERROR: ${error.stack}`);
  9. }
  10. }

在内部,异步函数写法更类似于 generators 。

以同步开始,异步处理的 async(异步) 函数

以下是 async(异步)函数是如何工作的:

  1. async(异步) 函数总是返回一个 Promise 对象 p 。Promise 对象在 async(异步) 函数开始执行时被创建。
  2. 函数体执行过程中,可以通过 return 或 throw 终止执行。或者通过 await 暂停执行,在这种情况下,通常会在以后继续执行。
  3. 返回 Promise 对象 p

当执行 async(异步) 函数的函数体时,return x 中的 x 是 Promise 对象 p 的完成状态的结果,而throw err 是 p 的拒绝状态的结果。执行结果是异步返回的。换句话说:then() 和 catch() 的回调总是在当前代码完成后执行。

以下是代码示例:

JavaScript 代码:
  1. async function asyncFunc() {
  2. console.log('asyncFunc()'); // (A)
  3. return 'abc';
  4. }
  5. asyncFunc().
  6. then(x => console.log(`Resolved: ${x}`)); // (B)
  7. console.log('main'); // (C)
  8. // Output:
  9. // asyncFunc()
  10. // main
  11. // Resolved: abc

您可以认为是以下的执行顺序:

  1. 行A:async(异步) 函数以同步开始。async(异步) 函数的 Promise 通过 return 来返回完成状态的结果。
  2. 行C:执行继续。
  3. 行B:Promise 完成状态通知是异步发生的。

返回不被包裹的 Promise 对象

Promise 的 resolve 是一项标准操作。 return 就是使用它来 resolve async(异步) 函数的 Promise p的。这意味着:

  1. 返回一个非 Promise 值,该值将被处理成 p 的完成状态值。
  2. 返回一个 Promise 对象,那么 p 此时相当于是该 Promise 的状态。

因此,您可以返回一个 Promise ,并且这个 Promise 不会包裹在别的 Promise 中:

JavaScript 代码:
  1. async function asyncFunc() {
  2. return Promise.resolve(123);
  3. }
  4. asyncFunc()
  5. .then(x => console.log(x)) // 123

有趣的是,返回一个拒绝状态(reject)的 Promise 对象会导致 async(异步) 函数被拒绝(reject)(通常,您可以使用 throw ):

JavaScript 代码:
  1. async function asyncFunc() {
  2. return Promise.reject(new Error('Problem!'));
  3. }
  4. asyncFunc()
  5. .catch(err => console.error(err)); // Error: Prob
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值