JavaScript中Promise嵌套机制解析及打印pending问题解惑
Promise嵌套的工作机制与代码问题解析
一、Promise嵌套的工作机制
当你在一个Promise的resolve方法中传入另一个Promise时,JavaScript会自动对这个嵌套的Promise进行解包操作:
- 如果传入的内层Promise处于
pending状态,外层Promise会保持pending,直到内层Promise的状态变为fulfilled或rejected; - 如果传入的内层Promise已经是
fulfilled状态,外层Promise会直接变为fulfilled,并将内层Promise的resolve值作为自己的最终值; - 如果传入的内层Promise是
rejected状态,外层Promise会直接变为rejected,并将内层的拒绝原因作为自己的拒绝原因。
简单来说,外层Promise会“穿透”内层Promise,最终的状态和值完全和内层Promise一致,不会出现Promise<Promise<值>>这种嵌套结构。
二、为什么控制台打印出Promise pending?
你的代码里,虽然内层Promisea被立即resolve(1)了,但resolve(a)触发的外层Promisek的状态更新是异步微任务,不会同步执行。而console.log(k)是同步代码,在执行它的时候,k的状态还没来得及更新,所以打印出来的是pending状态。
如果想看到k的最终状态和值,需要等到微任务执行完成后再打印,比如用setTimeout(宏任务,会在所有微任务之后执行)或者直接通过then回调:
// 方式1:用setTimeout延迟打印 setTimeout(() => console.log(k)); // 输出 Promise {<fulfilled>: 1} // 方式2:用then监听状态变化 k.then(val => { console.log(val); // 输出 1 console.log(k); // 输出 Promise {<fulfilled>: 1} });
另外你预期的Promise<Promise<1>>不会出现,就是因为前面说的自动解包机制,外层Promise会直接继承内层Promise的最终状态和值,最终k是一个值为1的已完成Promise。
内容的提问来源于stack exchange,提问作者Nikhil Harisinghani
相关产品推荐
相关产品推荐

