1const myPromise = Promise.resolve(Promise.resolve("Promise!")); 2 3function funcOne() { 4 myPromise.then(res => res).then(res => console.log(res)); 5 setTimeout(() => console.log("Timeout!"), 0); 6 console.log("Last line!"); 7} 8 9async function funcTwo() { 10 const res = await myPromise; 11 console.log(await res); 12 setTimeout(() => console.log("Timeout!"), 0); 13 console.log("Last line!"); 14} 15 16funcOne(); 17funcTwo();
本题为“单选题”
参考答案:
正确选项:D:Last line! Promise! Promise! Last line! Timeout! Timeout!
// 2023-03-04 更新解析
首先,我们调用 funcOne
。
在函数 funcOne
的第一行,我们调用myPromise
promise 异步操作。当JS引擎在忙于执行 promise,它继续执行函数 funcOne
。下一行 异步操作 setTimeout
,其回调函数被 Web API 调用。
promise 和 timeout 都是异步操作,函数继续执行当JS引擎忙于执行 promise 和 处理 setTimeout
的回调。相当于 Last line!
首先被输出, 因为它不是异步操作。
执行完 funcOne
的最后一行,继续往后执行 funcTwo
,但 funcTwo
函数内部第一行就是 await
阻止了后面代码的执行,所以才会去执行funcOne
中myPromise
的第一个then
。funcOne
中第一行的 promise
状态转变为 resolved,Promise!
被打印。
然而,我们调用了 funcTwo()
, 调用栈不为空,setTimeout
的回调仍不能入栈。
我们现在处于 funcTwo
,先 awaiting myPromise。通过 await
关键字, 我们暂停了函数的执行直到 promise 状态变为 resolved (或 rejected)。然后,我们输出 res
的 awaited 值(因为 promise 本身返回一个 promise)。 接着输出 Promise!
。
下一行就是 异步操作 setTimeout
,其回调函数被 Web API 调用。
我们执行到函数 funcTwo
的最后一行,输出 Last line!
。现在,因为 funcTwo
出栈,调用栈为空。在事件队列中等待的回调函数(() => console.log("Timeout!")
from funcOne
, and () => console.log("Timeout!")
from funcTwo
)以此入栈。第一个回调输出 Timeout!
,并出栈。然后,第二个回调输出 Timeout!
,并出栈。得到结果 Last line! Promise! Promise! Last line! Timeout! Timeout!
大家还可以想想,下面会输出什么:
1const myPromise = Promise.resolve(Promise.resolve("Promise!")); 2 3function funcOne() { 4 myPromise.then(res => { 5 console.log("执行第一个then", res) 6 return res 7 }).then(res => { 8 console.log('执行第二个then', res) 9 }); 10 setTimeout(() => console.log("Timeout!"), 0); 11 console.log("Last line!"); 12} 13 14async function funcTwo() { 15 console.log('进入funcTwo') 16 const res = await myPromise; 17 console.log('执行完第一个await,继续往下执行') 18 console.log(await res); 19 console.log('执行完第二个await,继续往下执行') 20 setTimeout(() => console.log("Timeout!"), 0); 21 console.log("Last line!"); 22} 23 24funcOne(); 25funcTwo();
最近更新时间:2023-07-05