javascript - 承诺链调用和单独调用之间的区别?
问题描述
代码示例1:
Promise.resolve().then(()=>{console.log('1')}).then(()=>{console.log('2')});
Promise.resolve().then(()=>{console.log('3')}).then(()=>{console.log('4')});
输出:
1
3
2
4
代码样本2:
Promise.resolve().then(()=>{console.log('1')});
Promise.resolve().then(()=>{console.log('2')});
Promise.resolve().then(()=>{console.log('3')});
Promise.resolve().then(()=>{console.log('4')});
输出:
1
2
3
4
我想第一个应该与第二个具有相同的输出。因为在示例 1 中,then
s 已经被顺序调用,并且回调应该是一个一个排列的。但结果似乎第二条线Promise.resolve
切入了。
我有什么误解吗?
解决方案
当被调用的 Promise 解决时,通过 a 添加的每个回调.then
都将被推送到微任务队列。
该队列将按 FIFO 顺序执行,每个微任务一旦执行就会从队列中移除。 .then
两种情况都在做非常不同的事情,为了更好地理解差异,这里是对两种情况的重写,没有任何链接并按执行顺序重新排序,但在执行方面与 OP 的版本相同。
const cb1 = ()=>{console.log('1')};
const cb2 = ()=>{console.log('2')};
const cb3 = ()=>{console.log('3')};
const cb4 = ()=>{console.log('4')};
// microtask queue []
const p1 = Promise.resolve(); // microtask queue [p1];
const p2 = Promise.resolve(); // microtask queue [p1, p2];
// p1() => add p3
const p3 = p1.then( cb1 ); // microtask queue [p2, p3];
// p2() => add p4
const p4 = p2.then( cb3 ); // microtask queue [p3, p4];
// p3() => cb1 + add p5
const p5 = p3.then( cb2 ); // microtask queue [p4, p5];
// p4() => cb3 + add p6
const p6 = p4.then( cb4 ); // microtask queue [p5, p6];
// p5() => cb2 // microtask queue [p6];
// p6() => cb4 // microtask queue [];
const cb1 = ()=>{console.log('1')};
const cb2 = ()=>{console.log('2')};
const cb3 = ()=>{console.log('3')};
const cb4 = ()=>{console.log('4')};
// microtask queue []
const p1 = Promise.resolve(); // microtask queue [p1]
const p2 = Promise.resolve(); // microtask queue [p1, p2]
const p3 = Promise.resolve(); // microtask queue [p1, p2, p3]
const p4 = Promise.resolve(); // microtask queue [p1, p2, p3, p4]
const p5 = p1.then( cb1 ); // microtask queue [p2, p3, p4, p5]
const p6 = p2.then( cb2 ); // microtask queue [p3, p4, p5, p6]
const p7 = p3.then( cb3 ); // microtask queue [p4, p5, p6, p7]
const p8 = p4.then( cb4 ); // microtask queue [p5, p6, p7, p8]
// p5() => cb1 // microtask queue [p6, p7, p8]
// p6() => cb2 // microtask queue [p7, p8]
// p7() => cb3 // microtask queue [p8]
// p8() => cb4 // microtask queue []
推荐阅读
- javascript - 将 CSV 从实时 URL 解析为 HTML 表
- c++ - 罗马数字转换程序抛出异常。新手问题
- vb.net - 将字符串保存到设置文件 System.Collection.Specialized.StringCollection 不起作用
- java - 用 Jackson 读取 YAML 会忽略没有值的键
- java - InflateException:膨胀类按钮时出错 - 通过 Play 商店崩溃
- express - ExpressJS 中的变量未在相同视图表单上定义
- c - Malloc使先前分配的指针无效?
- python - 在 Python3 中替换 Goose?
- php - Laravel 存储/插入数组值到数据库 Mysql
- asp.net-mvc - 创建新的 Stripe 源时出错 Invalid Token