ES7:generator + promise 的语法糖 async + await
为什么:
async
和await
关键字让我们可以用一种更简洁的方式写出基于Promise
的异步行为,而无需刻意地链式(then)调用promise
- 可以用同步的代码执行异步的操作
怎么用:
async
: 函数修饰符 控制函数返回**promise**
实例- 函数内部执行报错,则返回失败的
promise
实例,值是失败的原因 - 自己返回一个
promise
,以自己返回的为主 - 如果函数内部做了异常捕获,则还是成功态
- 函数内部执行报错,则返回失败的
使用async的主要目的:是为了在函数内部使用
**await**
[await必须在async里面]- await是异步的微任务
- 后面应该放置一个promise实例「我们书写的不是,浏览器也会把其变为promise实例」
- await中断函数体中,其下面的代码执行「await表达式会暂停整个async函数的执行进程并出让其控制权」
- 只有等待await后面的promise实例是成功态之后,才会把之前暂停的代码继续执行
- 如果await后面的promise实例是失败的,则下面的代码就不再执行了
- 简单说:函数体中遇到await,后面代码该咋地咋地,但是下面的代码会暂停执行「把他们当做一个任务,放置在EventQueue的微任务队列中」 ```javascript async function fn() { return 10; } console.log(fn());
- await是异步的微任务
// 使用async的主要目的:是为了在函数内部使用await function fn() { // await 1; Uncaught SyntaxError: await is only valid in async function }
function api(interval) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(interval); }, interval); }); }
// await:后面应该放置一个promise实例「我们书写的不是,浏览器也会把其变为promise实例」,await中断函数体中,其下面的代码执行「await表达式会暂停整个async函数的执行进程并出让其控制权」;只有等待await后面的promise实例是成功态之后,才会把之前暂停的代码继续执行,如果后面的promise实例是失败的,则下面的代码就不在执行了; // + await是异步的微任务 // + 函数体中遇到await,后面代码该咋地咋地,但是下面的代码会暂停执行「把他们当做一个任务,放置在EventQueue的微任务队列中」 async function func() { // await 1; //-> await Promise.resolve(1);
let result1 = await api(1000); console.log(result1);
let result2 = await api(3000); // await等上面的1秒完了才执行下面的代码 // 如果没有await,下面代码就直接执行了 console.log(result2); } func();
```javascript
async function foo() { return 1 }
等价于:
function foo() { return Promise.resolve(1) }
async function foo() { await 1 }
等价于
function foo() { return Promise.resolve(1).then(() => undefined) }
相继地调用:
- 类似同步
- 遇到 await,先执行后面的函数,该函数里面返回promise,创建一个宏任务
- await那行代码后面的代码作为微任务,需要等待await后面的函数执行成功后才执行
- 再写几个类似的代码,就构成了类似同步的效果,一个接一个执行
同时发生的:
执行顺序:
promise.all:
执行顺序: