为何两次生成的独立Promise仅执行第一个?解析resolve的作用
场景1:仅打印第一个延迟日志
代码如下:
function later(delayMillis) { return new Promise(function(resolve) { setTimeout(()=>{console.log('delay of ' + delayMillis + ' executed');}, delayMillis); }); } (async () => { await later(2000); await later(3000); console.log('This should print after minimum 5 seconds'); })();
问题:这段代码仅打印“delay of 2000 executed”,明明later(3000)是另一个独立的Promise,为什么第二个没被解析?
场景2:调用resolve后正常执行
修改后的代码:
function later(delayMillis) { return new Promise(function(resolve) { setTimeout(resolve, delayMillis); }); } (async () => { await later(2000); await later(3000); console.log('This should print after minimum 5 seconds'); })();
问题:改成在setTimeout里调用resolve后,两个Promise都能执行,最后一行日志也能正常打印,这是为什么?
原因解答
核心逻辑:Promise的状态切换规则
Promise有三种状态:pending(等待)、fulfilled(已完成)、rejected(已拒绝)。只有当Promise从pending状态切换到fulfilled或rejected时,await才会结束等待,继续执行后续代码。
场景1的问题根源
第一个later(2000)返回的Promise始终处于pending状态——因为你只在setTimeout里打印了日志,从来没调用resolve()。await会一直死等这个Promise完成,永远不会走到下一行的await later(3000),所以第二个Promise根本没机会被创建执行,自然不会打印“delay of 3000 executed”,最后一行日志也永远不会输出。场景2正常执行的原因
修改后的later函数在setTimeout里调用了resolve(),当定时器到时间时,Promise的状态会从pending变成fulfilled。await later(2000)等待2秒后,Promise完成,代码继续执行,创建并等待第二个later(3000)的Promise,3秒后这个Promise也完成,最后才执行console.log语句,所以所有日志都能按顺序输出。
简单总结:await会不会卡主,全看对应的Promise有没有被resolve或reject,没调用的话就一直挂着,后面的代码根本跑不到。
内容的提问来源于stack exchange,提问作者Stubborn

