V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
pursuer
V2EX  ›  JavaScript

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

  •  
  •   pursuer · 15 天前 · 900 次点击

    之前做了一次失败的尝试,做了一个 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 时有较高的性能损耗,所以只能说仅供参考,没什么实际应用价值

    3 条回复    2024-11-18 11:01:20 +08:00
    nightwitch
        1
    nightwitch  
       15 天前
    `new Error().stack`慢得要死,调用一次几十 ms 到到 100+ms 没了。
    IplayLF2
        2
    IplayLF2  
       13 天前
    https://github.com/thefrontside/effection effection 了解一下,能取消的并发任务,顺便还能了解下结构化并发。
    pursuer
        3
    pursuer  
    OP
       13 天前
    @IplayLF2 这类方案很多,我想实现的是在原生 async/await 上不需要侵入其他库的方案,不过实际搞下来不经过编译确实不行。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1074 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:24 · PVG 02:24 · LAX 10:24 · JFK 13:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.