Promise 中不调用 resolve 与 reject 产生的结果
有如下代码
// test.js
async function fun1() {
try {
await fun2();
} catch (error) {
console.log('error');
}
}
function fun2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
// resolve();
reject();
}, 500);
});
}
fun1();
在控制台执行 node test.js
,产生以下情况
- 在
fun2
的promise
中,如果我调用resolve
或者reject
,控制台会等待 500ms - 如果我不执行 setTimeout 他会立马结束程序执行
在我的理解中,promise
有三种状态:执行中、成功、失败
。既然我没有调用 resolve
或者 reject
他应该是一种 执行中
的状态,那么程序不应该结束才对,应该一直处于等待状态;实际的情况是,立马结束了,请问我的理解哪里出错了?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了让现象更清楚,我加大了
setTimeout
的时长,在这种情况下不执行resolve/reject
程序会在 10000ms 后结束。如果 “程序不应该结束才对,应该一直处于等待状态” 指的是10000ms后程序还应该在等待,那么可以这么理解:程序主线程执行
fun2
函数,函数入调用栈,执行new Promise
主体时遇到setTimeout
,setTimeout
会交由主线程外的 Web API 处理,fun2
函数执行完毕,此时任务队列为空已经没有任务需要执行,但程序还不能退出因为主线程外还有其他工作在进行,等到 10000ms 结束满足setTimeout
触发机制,回调函数进入宏任务队列,Event Loop 从宏任务队列取出任务执行,执行完毕,主线程和其他部门都没有在进行工作,程序退出。如果在
setTimeout
里调用了resolve/reject
只是往微任务队列里加了后续的回调步骤,主动调用那么程序会继续执行,不调用没任务要做了那么程序结束。这个问题其实不简单,参见 知乎上的这个问题。
我看了一些答案,得到的结论是:
Promise
应该一直pending
直到resolve
或者reject
(这种Promise
有专门的描述 “forever pending promise
”,说明 TC39 考虑过这个问题,但最终把此类Promise
的处理问题留给引擎开发者来解决);Promise
的状态,就算程序不结束,没被引用的Promise
所占内存都可能被回收,那它的状态就更不重要了。