分享一个可随时中断Promise的思路

/**
 * 封装一个可随时取消的Promise静态类
 * 所有需要随时可取消的Promise都需要用此类封装
 * 在任何地方想要取消时调用静态方法 IPromise.cancel()
 */
export class IPromise {
    private static tokens = []
    private static pop(reject: any) {
        let index = this.tokens.findIndex(item => item == reject)
        if (-1 != index) this.tokens.splice(index, 1)
    }
    /** 生成可取消的Promise */
    static new<T>(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T> {
        return new Promise((resolve, reject) => {
            this.tokens.push(reject)
            executor((value: T | PromiseLike<T>) => {
                this.pop(reject)
                resolve(value)
            }, (reason?: any) => {
                this.pop(reject)
                reject(reason)
            })
        })
    }
    /** 取消所有Promise */
    static cancel() {
        while (this.tokens.length > 0) {
            this.tokens.pop()("中断执行")
        }
    }
}

使用方法

    async start() {
        setTimeout(()=>{
            IPromise.cancel()
        },2000)
        try {
            // 如果使用await的方式 后面不能使用catch处理异常 留给try catch捕获 
            let result = await this.asyncHandler(1)
            console.log("result:", result)
            // 如果使用then接收结果 后面必须使用catch来处理异常
            this.asyncHandler(2).then(result => {
                console.log("result:", result)
            }).catch(console.error)

            this.asyncHandler(3).then(result => {
                console.log("result:", result)
            }).catch(console.error)
       
            console.log(await this.asyncHandler(4))

        } catch (error) { 
            console.error(error)
        }
    }
    asyncHandler(value: any) {
        return IPromise.new((resolve, reject) => {
            setTimeout(() => {
                resolve(value)
            }, 1000)
        })
    }

注意!这个方法未经过大量测试 只是个思路 慎用! 如果有更好的方法可以讨论下

1赞

我一般爱用rxjs做这异步的逻辑

3.0的话貌似用不了吧

不知道哦,我还没用过3.+,不过不是支持npm了吗?
我用2.4.4

3.0 不支持npm 好多npm包用不了

请问如何在3.x中通过npm使用rxjs? 我再3.2中使用时,打开一直报错404

最近刚刚在3.3.0解决了这个问题。就是用的源码。使用体验还是不错的,但我并没有机会在实际的3.3的项目中使用。
3.0的rxjs模块如何导入呢? - Creator 3.0 - Cocos中文社区