网站开发语言手册,支付公司网站建设费账务处理,网站整站截图,wordpress软件概述
理解 Promise 的执行顺序时#xff0c;需要牢记以下两点#xff1a; 微任务与宏任务的优先级#xff1a; 微任务#xff1a;Promise.then()、catch、finally 是微任务。宏任务#xff1a;setTimeout、setInterval 是宏任务。微任务的优先级高于宏任务#xff1a;在…概述
理解 Promise 的执行顺序时需要牢记以下两点 微任务与宏任务的优先级 微任务Promise.then()、catch、finally 是微任务。宏任务setTimeout、setInterval 是宏任务。微任务的优先级高于宏任务在一次事件循环中先清空所有的微任务队列再执行下一个宏任务。 Promise 是基于微任务实现的 当一个 Promise 的状态变为 resolved 或 rejected 时它的 .then() 回调会被加入微任务队列等待当前任务包括微任务完成后执行。 示例代码分析
代码分析
以下代码可以帮助理解 Promise 和 setTimeout 的执行顺序
console.log(script start);setTimeout(() {console.log(setTimeout 1);
}, 0);Promise.resolve().then(() {console.log(promise 1);return Promise.resolve().then(() {console.log(promise 2);});}).then(() {console.log(promise 3);});setTimeout(() {console.log(setTimeout 2);
}, 0);console.log(script end);执行过程解析 同步任务立即执行 console.log(script start) 输出 script start.setTimeout 的两个回调函数被放入 宏任务队列等待事件循环调度。Promise.resolve() 被调用then() 的回调被放入 微任务队列。 输出结果 script start
script end主线程执行完同步任务后开始执行微任务队列 微任务队列的顺序如下 第一个 .then() 输出 promise 1 并返回一个新的 Promise。新的 Promise.then() 输出 promise 2。第二个 .then() 输出 promise 3。 输出结果 promise 1
promise 2
promise 3清空微任务队列后开始执行宏任务队列 宏任务队列的两个 setTimeout 回调依次执行输出 setTimeout 1 和 setTimeout 2。 输出结果 setTimeout 1
setTimeout 2最终输出
综合以上代码的输出顺序为
script start
script end
promise 1
promise 2
promise 3
setTimeout 1
setTimeout 2总结
同步任务优先执行输出 script start 和 script end。微任务队列优先于宏任务队列。Promise.then() 的回调会依次进入微任务队列。setTimeout 的回调进入宏任务队列最后执行。
(拓展)问题补充
如果第一个then不是返回return promise而是直接执行一个Promise.resolve().then(() { console.log(promise 2); });结果是不是 会变成 promise 1 → promise 3 → promise 2。结果是的。
为什么会这样
当 Promise.resolve().then() 不通过 return 将内部的 Promise 链接到外部 then 时promise 2 的执行不再是当前链的一部分它会被单独添加到 微任务队列的末尾导致执行顺序的变化。 示例代码
以下是修改后的代码
console.log(script start);Promise.resolve().then(() {console.log(promise 1);Promise.resolve().then(() {console.log(promise 2);});}).then(() {console.log(promise 3);});console.log(script end);执行过程解析 同步任务 输出 script start。主线程继续将第一个 Promise.then() 的回调加入 微任务队列。输出 script end。 当前输出 script start
script end微任务队列开始执行 执行第一个 .then()输出 promise 1。 在此回调中一个新的微任务promise 2 的回调被加入 微任务队列末尾。执行第二个 .then() 的回调输出 promise 3。 当前输出 promise 1
promise 3微任务队列剩余任务 微任务队列中剩余的任务是 promise 2 的回调输出 promise 2。 最终输出 promise 2总输出结果
综合以上完整的输出顺序是
script start
script end
promise 1
promise 3
promise 2关键点解析 链式调用和微任务队列 当你不通过 return 将一个新的 Promise 链接到当前 then它的回调会独立加入 微任务队列的末尾而不是成为当前链的一部分。 对比返回 Promise 如果 return Promise.resolve().then(...)那么 promise 2 的执行会成为当前链的一部分顺序为 promise 1 → promise 2 → promise 3。 改变的核心代码 独立的微任务 Promise.resolve().then(() {console.log(promise 2);
});作为链的一部分 return Promise.resolve().then(() {console.log(promise 2);
});两种写法的区别在于是否将新的 Promise 加入当前链。