搞懂一道async await, promise, setTimeout执行顺序的前端面试题
先指明这道题是面试题的改版,原题可以看: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
大家可以和最上面的结果对比一下,哈哈!完全一样。
这道题应该算是明白了,但是我又发现一个新的问题,现在还没搞明白,请大神解答