async 函数中止/task local 方案后记,V8 上的另一个可行思路

1 天前
 pursuer

之前做了一次失败的尝试,做了一个 hook Promise 的方案。
https://www.v2ex.com/t/1081474
省流说下这个方案失败的原因是 native code 中(例如 fetch)创建的 promise 不会使用 Hooked 的 Promise ,并且 V8 原生 await 实现不会在 onfulfilled 返回前运行 await 后面的代码,只有通过类似 babel 等工具将 await 编译为生成器函数的情况下才行。
后来我把库改回了生成器函数的模式。

昨天突发奇想,想到另一个方案,这个方案我测试在 node 和 chrome 上是可行的。 就是借助 new Function 自定义一个带标记的函数,就可以将标记的函数名插入到 new Error().stack ,就可以区分当前的任务栈,实现 task local,继而也可以通过 hook promise 实现 async 函数中止。虽然和最早方案的表现有一些差异。这个方案经过测试确实是可行的。

但是这个方案只在 V8 测试是生效的,在 txiki.js(quickjs)上 await 的堆栈会丢失。并且在获取当前 task 时有较高的性能损耗,所以只能说仅供参考,没什么实际应用价值

413 次点击
所在节点    JavaScript
1 条回复
nightwitch
19 小时 56 分钟前
`new Error().stack`慢得要死,调用一次几十 ms 到到 100+ms 没了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1090081

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX