@
iceprosurface @
mc2tap @
NoManPlay > iceprosurface:我记得理论上 Promise.resolve().then 的回调函数会在当前同步代码执行完毕后加入微任务队列的。
是因为 then 和 resolve() 是处于同一块同步代码,resolve 的时候本来可以添加 microtask 的,但是由于 then 还没有被执行所以没有 task 可以添加。
> iceprosurface:至于 console 1212 因为 await 的原因应该是要等到整个微任务队列清空以后才会执行的吧,这种代码我觉得纯 八股文,如果要保证时序,应该从业务考虑
不是因为 await 的原因,await 我觉得其实就是将当前任务的后续代码包裹成一个 callback 然后用 then 调用了(可能说法有错误),我觉得也不算八股文吧,至少让我搞清楚了 Promise 原理,下次用 Promise 会更有底气不出错,我感觉这样至少心理上挺爽的哈哈。
> NoManPlay: Promise 本身是宏任务,要执行完同步任务和微任务后再执行.then/await
我认为 new Promise 的 executer 是同步代码,await 是语法糖,将代码包装成 .then 的回调函数,然后当 Promise resolve 的时候会将已经存在的 onFulfilleds 或者 onRejects 添加为 microtask ,全部过程中我不知道哪个是宏任务,不在认知中
> mc2tap:自己照着 Promise A+实现一遍 Promise 就知道了
我看了,但是水平有限最终还是去看别人的实现了,但是看了半天也没关联到这个问题的具体答案,我后面又遇到一个问题,[去 StackOverflow 上问了](
https://stackoverflow.com/questions/79455607/when-does-promise-resolve-reject-actually-add-a-micro-task#comment140127364_79455607),然后连带着这个问题也知道答案了,其实就是 resolve 的时候还没有注册回调函数,所以导致无任务可以添加,直到执行了 then 才添加了任务,被回答者的说法点拨了,我惊觉后回来看这个帖子的问题,答案也是相同的。
我添加了 setTimeout ,延后了 resolve 和 addMicro 的执行之后,添加 microtask 的次序就按照我想的来了:
```js
const delay = async (time) => {
return new Promise((resolve) => setTimeout(resolve, time));
};
const busy = (time) => {
const now = new Date();
while (new Date() - now < time) {}
};
const getNum = () => {
console.log("getnum 执行");
return new Promise(async (resolve, reject) => {
console.log("promise 开始");
setTimeout(() => {
resolve(1);
addMicro("haha");
});
console.log("promise 结束");
});
};
const addMicro = (str) => {
Promise.resolve().then(() => {
console.log(`micro task ${str}`);
});
};
getNum().then(() => {
console.log("1212");
});
···
这个代码是先输出 1212 再输出 micro task haha 的