javascript - 当我们返回一个值以及从微任务队列中的 then() 链返回 Promise.resolve 时会发生什么?
问题描述
在这里,我有一个简单解决的承诺。
let promise = new Promise((resolve,reject)=>{
resolve("resolved");
});
.then
当我在链中使用 Promise 作为返回值时,我的困惑就开始了:
promise.then(resolve=>{
console.log(resolve);
return Promise.resolve(2);
}).then(resolve=>{
console.log(resolve);
});
promise.then(resolve=>{
console.log(resolve)
return 3;
}).then(resolve=>{
console.log(resolve);
});
这些链的输出是:1 1 3 2 我期望看到的:1 1 2 3
但是如果我像这里一样return Promise.resolve(2);
转向:return 2
promise.then(resolve=>{
console.log(resolve);
return 2;
}).then(resolve=>{
console.log(resolve);
});
promise.then(resolve=>{
console.log(resolve)
return 3;
}).then(resolve=>{
console.log(resolve);
});
我会得到我认为我首先会得到的输出(1 1 2 3)。
那么这里的任何人都可以解释为什么输出会根据 using 和 not using 发生变化Promise.resolve()
吗?
顺便说一句,我问这个问题只是为了纯粹的学术原因!
解决方案
then
Promises的s 在微任务期间解决。在 a.then
中,如果您返回一个普通值,例如 2 或 3,则.then
链接到它的下一个将在下一次调用堆栈被清除时运行。但是,如果您返回一个 Promise,则必须先将其解包,然后再进行下一个.then
。
在您的第一个代码中,一旦调用堆栈被清除,第一个微任务就会运行。其中之一“解包”Promise.resolve(2)
并.then
在微任务队列中将回调排队。相反,3
不需要解包,因此它会.then
立即运行,无需等待,记录 3。
微任务队列的顶部任务是2
's .then
,记录 2。
综上所述,在实际代码中,您不必依赖这种时序,因为它有点令人困惑——如果这是一个问题,最好重新构建代码,这样就不用担心了。
推荐阅读
- security - 英特尔的 PTT 和 TPM 是否等效
- jenkins - Jenkins 升级到 LTS 2.249.1 - 缺少侧栏面板菜单
- c - sizeof 运算符返回 16 位处理器系统
- python - TypeError:'set' 对象不可调用 discord.py
- terraform - 我们可以使用 terraform 或 gcloud 命令更改 GCP 云构建设置吗
- php - 按角色过滤用户 Laravel
- python - Scraping specific data from edgar
- mysql - 如果使用 sprintf 将 MYSQL_ROW 中的字段放入 char 数组中不会崩溃,这只是运气吗?
- c# - 如何在c#中将八个数字'0'和'1'字符的数组转换为字节
- javascript - 如何将 localStorage 用于活动链接