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

来源:互联网 发布:淘宝小二误判如何申诉 编辑:程序博客网 时间:2024/06/09 21:14

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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小孩发烧后又吐怎么办 11个月宝宝吐了怎么办 11个月宝宝拉肚子怎么办 2岁宝宝反复呕吐怎么办 1岁半幼儿拉肚子怎么办 宝宝打嗝呕吐胃难受怎么办 3岁宝宝发烧还吐怎么办 孩子喝水都吐怎么办啊 宝宝吃多了呕吐怎么办 3岁宝宝吐怎么办才好 儿童受凉肚子疼发热呕吐怎么办 两岁宝宝半夜呕吐怎么办 两岁宝宝吐了怎么办 2岁宝宝发烧吐怎么办 2岁多宝宝呕吐是怎么办 2周岁宝宝中暑了怎么办 2岁半宝宝着凉呕吐怎么办 3岁宝宝吐了几次怎么办 一岁宝宝恶心吐怎么办 9个月宝宝一直吐怎么办 晚上冻着了呕吐怎么办 2岁宝宝一直吐怎么办 两岁宝宝门牙龋齿怎么办 两岁宝宝得龋齿怎么办 两岁宝宝长龋齿怎么办 宝宝2岁不吃饭怎么办 两岁宝宝总是吐怎么办 3岁儿童受凉呕吐怎么办 两岁宝宝四天没拉大便怎么办 两岁宝宝发烧吐怎么办 四岁宝宝吐了怎么办啊 3岁宝宝突然吐了怎么办 宝宝撑着了吐拉怎么办 2岁宝宝体温37.5怎么办 宝宝2岁乳牙烂了怎么办 孕40周还没入盆怎么办 孕妇脸上长斑了怎么办 七个月宝宝大便干怎么办 两月大婴儿不拉大便怎么办 周岁宝宝大便出血了怎么办 十一个月宝宝大便干燥怎么办