一、async/await的用法
async用于修饰一个函数使函数返回一个Promise 对象。
async function testAsync() {return "hello async";
}const result = testAsync();
console.log(result);
await必须在用async修饰的函数中使用,await用于修饰一个语句,awit的返回值为该语句的值,如果awit修饰的语句为Promise 对象,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
async function async2() {return "async2"}function async3() {return new Promise(function(resolve) {resolve("async3")})}async function async1() {const v1 = await "async1";const v2 = await async2();const v3 = await async3();console.log(v1, v2, v3);}async1();//async1 async2 async3
二、async/await的作用
假设一个业务,分多个步骤完成,每个步骤都是异步的,而且依赖于上一个步骤的结果。如果用Promise 通过 then 链来解决需要多层回调,而用async/await在解决就容易很多
用promise实现
function takeLongTime(n) {return new Promise(resolve => {setTimeout(() => resolve(n + 200), n);});
}function step1(n) {console.log(`step1 with ${n}`);return takeLongTime(n);
}function step2(n) {console.log(`step2 with ${n}`);return takeLongTime(n);
}function step3(n) {console.log(`step3 with ${n}`);return takeLongTime(n);
}
function doIt() {console.time("doIt");const time1 = 300;step1(time1).then(time2 => step2(time2)).then(time3 => step3(time3)).then(result => {console.log(`result is ${result}`);console.timeEnd("doIt");});
}doIt();
用async/await实现
function takeLongTime(n) {return new Promise(resolve => {setTimeout(() => resolve(n + 200), n);});
}function step1(n) {console.log(`step1 with ${n}`);return takeLongTime(n);
}function step2(n) {console.log(`step2 with ${n}`);return takeLongTime(n);
}function step3(n) {console.log(`step3 with ${n}`);return takeLongTime(n);
}
async function doIt() {console.time("doIt");const time1 = 300;const time2 = await step1(time1);const time3 = await step2(time2);const result = await step3(time3);console.log(`result is ${result}`);console.timeEnd("doIt");
}doIt();
代码结构是不是清晰很多
三、async/await的执行顺序
阅读这篇需要对JS的执行顺序有深入的了解,如果有不懂的可以阅读我的这一篇博客:[由浅入深解释JS执行机制 EventLoop]
(https://blog.csdn.net/weixin_42210204/article/details/101942555)
await阻断后的任务属于微任务,放入微任务队列中
console.log("start");async function async1() {console.log("async start");await console.log("await");console.log("async end");}async1();console.log("end");
依次输出 start->async start->await->end->async end
依次执行 到console.log(“await”);后遇到await,阻断await之后的任务,放入微任务列表,执行完所有宏任务后,在执行微任务列表里的console.log(“async end”);
console.log("start");function as() {return new Promise(resolve => {console.log("as");resolve();}).then(function() {console.log("then");})}async function async1() {console.log("async start");await as();console.log("async end")}async1();new Promise(resolve => {console.log("promise");resolve();}).then(function() {console.log("then1")})console.log("end");
依次输出start->async start->as->promise->end->then->then1->async end
注意then1和async end的输出顺序,执行第一个微任务输出then后,遇见await又将console.log(“async end”)放入了微任务的队尾。
类似于以下这种情况:
console.log("start");new Promise(resolve => {console.log("promise1");resolve();}).then(function() {console.log("then1");new Promise(resolve => {console.log("promise2");resolve();}).then(function() {console.log("then2");})})new Promise(resolve => {console.log("promise3");resolve();}).then(function() {console.log("then3");})console.log("end");
依次输出:start->"promise1->promise3->end->promise2->then3->then2