写过 JS 的都知道 JS/TS 的异步方案采用 async,await,Promise 的无栈协程方案。Python 也是采用的类似方案,但 Python 提供更多的控制包括 cancel 一个 task ,可以尝试提前结束一个异步任务,同时 JS/TS 也没有 current_task 或者类似 Java 的 ThreadLocal 获取上下文变量的方案。

通常的实现中断执行的写法是手动判断类似 AbortSignal.throwIfAborted 的方案,但写起来没那么舒心。

于是我想到是否可以通过改写 Promise.then 实现自动中断 await 执行?实际写下来以后的发现居然真的可以,于是有了下面的这个库。

https://github.com/partic2/protask

https://gitee.com/partic/protask

使用示例:


``` typescript

import {task} from 'protask'

function sleep<T>(milliSeconds: number, arg?: T): Promise<T> {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, milliSeconds, arg)
    });
}

async function printTaskLocal(){
    await sleep(100);
    console.info(task.locals());
}

task.create('test task 1',async ()=>{
    try{
        for(let i=0;i<100;i++){
            task.locals()!.count=i;
            await printTaskLocal();
            await sleep(1000)
        }
    }catch(e:any){
        console.info(e.toString());
    }
});

task.create('test task 2',(async ()=>{
    await sleep(3000);
    console.info('abort task 1')
    task.abort('test task 1');
}));

```

上面的代码创建了一个 task1 然后在 task2 中中断了 task1 的运行。同时在 task1 中打印 task local 。


目前只是一个非常简单实验性质的库,并未完善测试过,请注意使用风险。

觉得有意思的话可以点个 star ,万一以后就进 tc39 了呢?(笑
举报· 325 次点击
登录 注册 站外分享
5 条回复  
1una0bserver 小成 2024-10-19 14:13:04
@dapang1221 大前端不是早就搞成操作系统了吗🤔
9ki 小成 2024-10-18 16:05:51
分享一个全功能的 Promise

http://bluebirdjs.com/docs/features.html#cancellation-and-timeouts
dapang1221 小成 2024-10-18 14:18:11
啊?你们前端终于把浏览器搞成了操作系统了吗
nomagick 小成 2024-10-18 13:49:45
不是这样的,你这没有作用。。

主动中断同步代码目前只能通过操作系统,中断线程或中断进程
主动中断异步代码,可以通过 iterator 在 yield 的节点中断,但在 js 语法之外需要魔改

你这只是在上游 then 之后选择是否往下游返回,没有中断任何代码的执行,掩耳盗铃了属于是
rppig42 小成 2024-10-18 13:46:28
👍

有正经这个需求的可以了解下 RxJS
返回顶部