前言
async和await是ES6提出来的处理异步函数的。但是它们是如何执行的,执行顺序又是怎样的?这篇文章将会为你揭晓。
async/await
- async/await是一种编写异步代码的新方法。之前异步代码的方案是回调和promise。
- async/await是建立在promise的基础上。
- async/await像promise一样,也是非阻塞的。
- async/await让异步代码看起来、表现起来更像同步代码。
async怎么处理返回值
async function testAsync() {
return 'hello async';
}
let result = testAsync();
console.log(result); // Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "hello async"}
小结:从结果中可以看出async函数返回的是一个promise对象,如果在函数中return一个直接量,async会把这个量通过Promise.resolve()封装成Promise对象。
如果async函数没有返回值
async function testAsync1() {
console.log('hello, async!');
}
let result = testAsync1();
console.log(result); // Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "undefined"}
小结:结果返回了Promise.resolve(undefined);
await等待的是一个表达式,这个表达式的返回值可以是一个Promise对象也可以是别的值。很多人以为await会一直等待之后的表达式执行完成后才会继续执行后面的代码,实际上await是一个让出线程的标志。await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈(后面会详述)的代码,等本轮事件循环执行完了之后又会跳回到async函数中等待await后面表达式的返回值,如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise队列。
async/await 执行顺序
代码示例:
function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
async function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
const v1 = await testSometing();//关键点1
console.log(v1);
const v2 = await testAsync();
console.log(v2);
console.log(v1, v2);
}
test();
var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//关键点2
promise.then((val)=> console.log(val));
console.log("test end...")
// 执行结果
//test start...
//执行testSometing
//promise start..
//test end...
//testSometing
//执行testAsync
//promise
//hello async
//testSometing hello async
执行顺序分析:
// 执行栈
console.log("test start...");
//执行到const v1 = await testSometing()时,因为await会让出线程,就会去执行后面的代码
var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//关键点2
// 执行栈
console.log("test start...");
console.log("执行testSometing");
////////
console.log("promise start..");
console.log("test end...");
// Promise队列:
promise.then((promise)=> console.log(promise));
继续执行await后面的代码
// 执行栈
console.log("test start...");
console.log("执行testSometing");
////////
console.log("promise start..");
console.log("test end...");
///////
console.log(v1);// v1 = testSometing
// Promise队列:
promise.then((promise)=> console.log(promise));
执行到const v2 = await testAsync();
// 执行栈
console.log("test start...");
console.log("执行testSometing");
////////
console.log("promise start..");
console.log("test end...");
///////
console.log(v1);// v1 = testSometing
//////
console.log("执行testAsync");
// Promise队列:
promise.then((promise)=> console.log(promise));
跳出test,继续执行后面的代码
// 执行栈
console.log("test start...");
console.log("执行testSometing");
////////
console.log("promise start..");
console.log("test end...");
////////
console.log(v1);// v1 = testSometing
////////
console.log("执行testAsync");
////////
console.log(promise);
继续执行await后面的代码
// 执行栈
console.log("test start...");
console.log("执行testSometing");
////////
console.log("promise start..");
console.log("test end...");
////////
console.log(v1);// v1 = testSometing
////////
console.log("执行testAsync");
////////
console.log(promise);
////////
console.log("hello async");
console.log("testSometing hello async");