先指明这道题是面试题的改版,原题可以看:promise、async和await之执行顺序的那点事
这道题也不是我改的,出处见:async/await 执行顺序详解
这两篇文章写的非常好,我仔细琢磨了一下,感觉受益匪浅,决定记录一下自己的理解。
不再废话,下面见题:
async 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();
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");});//3
promise.then((val)=> console.log(val));
console.log("test end...")
输出结果:
1 test start...
2 执行testSometing
3 promise start..
4 test end...
5 promise
6 testSometing
7 执行testAsync
8 hello async
9 testSometing hello async
这道题最难理解的地方5和6的执行顺序,前面1~4的结果一般没有异议,如果不明白,百度一下变可以理解。
5的结果是promise的then方法里输出的,6打印的第一个await的返回结果。
下面先说一下async的await:
async 函数中可能会有 await 表达式,这会使 async 函数暂停执行,将await的结果封装成一个Promise,并等待解析完成后继续执行,
另外如果await 遇上async函数,阮一峰老师这么说明:
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
所以如果await遇到了 async函数,就会封装两次Promise,即:
const v1 = await testSometing();
可以理解成下面的代码:
new Promise((resolve)=> {
resolve(Promise.resolve(testSometing()));
}).then((val)=>{
const v1 = val
...
})
按照这个思路,将题目await 都替换成promise:
function testSometing() {
console.log("执行testSometing");
return "testSometing";
}
function testAsync() {
console.log("执行testAsync");
return Promise.resolve("hello async");
}
async function test() {
console.log("test start...");
new Promise((resolve)=> {
resolve(Promise.resolve(testSometing()));
}).then((val)=>{
const v1 = val
console.log(v1);
new Promise((resolve)=> {
resolve(Promise.resolve(testAsync()));
}).then((val)=>{
const v2 = val
console.log(v2);
console.log(v1, v2);
})
})
}
test();
var promise = new Promise((resolve)=> { console.log("promise start.."); resolve("promise");});//3
promise.then((val)=> console.log(val));
console.log("test end...")
执行的结果如下:
test start...
执行testSometing
promise start..
test end...
promise
testSometing
执行testAsync
hello async
testSometing hello async
大家可以和最上面的结果对比一下,哈哈!完全一样。
这道题应该算是明白了,但是我又发现一个新的问题,现在还没搞明白,请大神解答
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。