多Promise链场景下微任务执行顺序的规则疑问与权威资料咨询
多Promise链场景下微任务执行顺序的规则疑问与权威资料咨询
出于学术研究的兴趣,我一直在探究多Promise链场景下的微任务执行顺序,下面是我做的几组测试和遇到的疑问:
I. 两条Promise链
它们会以一种可预测的「交错(zipped)」方式执行:
Promise.resolve() .then(log('a1')) .then(log('a2')) .then(log('a3')); Promise.resolve() .then(log('b1')) .then(log('b2')) .then(log('b3')); // a1 b1 ; a2 b2 ; a3 b3 // 这里和其他输出列表中 // 手动添加的分号 ";" 是为了辅助说明我的理解
II. 第一个"a1"返回一个Promise
Promise.resolve() .then(() => { log('a1')(); return Promise.resolve(); }) .then(log('a2')) .then(log('a3')); Promise.resolve() .then(log('b1')) .then(log('b2')) .then(log('b3')); // a1 b1 ; b2 ; b3 a2 ; a3
我的理解是:从then()中返回一个新的Promise会引入一个额外的微任务来解析这个Promise;这也把"A"链的then()推到了“循环”的末尾,导致"b2"和"b3"都能先于后续的A链回调执行。
III. 三条Promise链
下面是可运行的测试代码,包含辅助函数:
const output = []; const makeChain = (key, n = 5, trueStep = false) => { let p = Promise.resolve(); const arrow = isArrow => isArrow ? '->' : ''; for (let i = 1; i <= n; i++) { const returnPromise = trueStep === i; const afterPromise = trueStep === i - 1; p = p.then(() => { output.push(`${arrow(afterPromise)}${key}${i}${arrow(returnPromise)}`); if (returnPromise) return Promise.resolve(); }); } return p.catch(console.error); }; // ----- 分割线,用于后续测试 ----- Promise .all([ makeChain('a', 3), makeChain('b', 3), makeChain('c', 3), ]) .then(() => console.log(output.join(' '))); // a1 b1 c1 ; a2 b2 c2 ; a3 b3 c3
目前一切符合预期:依然是「交错」执行。
IV. 在"a1"步骤返回Promise
(省略辅助函数)
Promise .all([ makeChain('a', 3, 1), makeChain('b', 3), makeChain('c', 3), ]) .then(() => console.log(output.join(' '))); // a1-> b1 c1 ; b2 c2 ; b3 c3 ->a2 ; a3
看起来和之前的表现一致:"A1"引入了一个额外的微任务,同时把A链后续的回调推到了“循环”的末尾。
V. "c4"也返回Promise
Promise .all([ makeChain('a', 7, 1), makeChain('b', 7), makeChain('c', 7, 4), ]) .then(() => console.log(output.join(' '))); // a1-> b1 c1 ; b2 c2 ; b3 c3 ->a2 ; b4 c4-> a3 ; b5 a4 ; b6 a5 b7 ->c5 ; a6 c6 ; a7 c7
两个疑问
- 在最后一组测试中,执行到"c4"之后,为什么"b7"会先于"c5"的
then()执行? - 在哪里可以查阅到PromiseJobs队列中微任务执行顺序的官方规则?
备注:内容来源于stack exchange,提问作者Serge
相关产品推荐
相关产品推荐

