TGTGInsighttelegram intelligenceLIVE / telegram public index
← Arki 的每日 BUG 观察
Arki 的每日 BUG 观察 avatar

TGINSIGHT POST

Post #507

@arkibug

Arki 的每日 BUG 观察

Views60帖子阅读量
发布9月14日2024/09/14 04:48
Post content

帖子内容

首先众所周知 setTimeout 是平台的 API,可以直接判断平台 API 在所有 promise 后面走 event loop(不过现在有个例外 queueMicrotask,平台 API 但是不是 event loop,这个倒是可以搞到 JS 规范里)。 然后我对代码执行的建模是这样的: Promise Reaction Job 队列(微任务队列)里面存了已经解决的 Promise 的 Reaction(then/catch/finally) 开始执行代码时,(初次运行时)先执行所有同步的代码, 然后按顺序执行所有的 Promise Reaction Job 里的 Reaction。 执行代码时新解决的 Promise 上面挂的 Reaction 就会推到队列里。 全部执行完毕之后 idle,等待 event loop 中的事件触发下一次执行代码。 对于上面的代码,我的理解过程是这样的(不提 setTimeout 因为肯定是最后一个): line 5:首先同步执行 promise 的构造器,log-promise 然后直接解决了 promise(也就是说接下来附加到这个 promise 的 reaction 会直接进队列),目前队列是空的,因为 promise 没有 reaction。 line 10: async iife 和 new Promise 没什么区别,所以 log async start。 line 12: await promise 了(参考规范 27.7.5.3),首先判断是不是平凡的 Promise,如果不是还得包一层(step 2)。 生成两个 reaction,一个是被 await 的 promise resolve 了之后执行的代码,一个是 reject 之后(step 3 和 5)。 然后规范 step 7 直接执行了 promise.then(第一个 reaction,第二个reaction),然后暂停了当前 async function 的执行。 因为 promise 已经解决了,所以把第一个 reaction 排进队列(队列里的第一个 reaction) line 16: 再给 promise 挂一个 resolve reaction。同理,进队列,排在上面那个的后面 line 20: log-end 此时同步代码已经执行完了,接下来按顺序执行队列打出 promise resolve 和 log-promise1-then。 假如在 line 13 前面加 promise.then(() => ...),那它按队列,排在 log-promise1-then 后面。