sailei1 / blog

1 stars 0 forks source link

PromiseTaskRunner #117

Closed sailei1 closed 2 years ago

sailei1 commented 2 years ago
/**
 * 使用Promise工具添加顺序执行任务的工具类
 */
export default class PromiseTaskRunner {

    private m_doList = [];
    private m_LoadCnts: number = 0;
    private m_MaxCnts: number = 0;
    private m_started: boolean = false;
    private m_finishCb: Function = null;
    private m_failCb: Function = null;

    public get IsLoaded(): boolean {
        return this.m_started && this.m_LoadCnts >= this.m_MaxCnts;
    }

    public get LoadCnts(): number {
        return this.m_LoadCnts;
    }

    public get MaxCnts(): number {
        return this.m_MaxCnts;
    }

    public set FinishCb(value: Function) {
        this.m_finishCb = value;
    }

    public set FailCb(value: Function) {
        this.m_failCb = value;
    }

    // 是否加载失败
    private m_isLoadFailed: boolean = false;
    public get IsLoadFailed(): boolean {
        return this.m_isLoadFailed;
    }
    public set IsLoadFailed(value: boolean) {
        this.m_isLoadFailed = value;
    }

    /**
     * 添加Promise化任务函数
     * @param taskPromise Promise化任务函数
     */
    public Push(taskPromise: Promise<any>) {
        this.m_doList.push(taskPromise);
        this.m_MaxCnts = this.m_doList.length;
    }

    public Unshift(taskPromise: Promise<any>)
    {
        this.m_doList.unshift(taskPromise);
        this.m_MaxCnts = this.m_doList.length;
    }

    public PopTask()
    {
        this.m_doList.shift();
    }

    /**
     * 开始执行Promise化任务函数列表
     */
    public Start() {
        this.m_started = true;
        this.queue(this.m_doList);
    }

    public GetTaskNum():number
    {
        return this.m_doList.length;
    }

    private queue(arr) {
        let that = this;
        let sequence: Promise<any> = Promise.resolve();
        arr.forEach(function (item) {
            sequence = sequence.then(item).then((res) => {
                that.m_LoadCnts ++;
                return Promise.resolve(res);
            });
        })

        sequence = sequence.then(res => {
            that.onTaskFinished(res);
            return Promise.resolve("success");
        }).catch((reason:any) => {
            console.error('PromiseTaskRunner task sequence catch reason:', reason)
            that.onTaskFailed(reason);
        })

        return sequence;
    }

    // 重新从上次下载失败的任务开始执行下载任务
    private RetryFromFailedTask() {
        this.m_isLoadFailed = false;
        let doList = this.m_doList.slice(this.m_LoadCnts);
        this.queue(doList);
    }

    // 加载成功,重置加载失败标志
    private onTaskFinished(res) {
        if (this.m_LoadCnts >= this.m_MaxCnts) {
            this.m_isLoadFailed = false;
        }
        this.m_finishCb && this.m_finishCb(res);
    }

    // 加载失败
    private onTaskFailed(reason) {
        this.m_isLoadFailed = true;
        this.m_failCb && this.m_failCb(reason);
    }

    // 调用此接口进行加载失败重试
    public RetryLoadingOnFailed() {
        let that = this;
        that.IsLoadFailed = false;
        // 直接自动重连
        that.RetryFromFailedTask();
    }
}
 this.m_taskRunner = new PromiseTaskRunner();
        this.m_taskRunner.FailCb = (reason) => {
            this.m_taskRunner.RetryLoadingOnFailed();
        };
        this.m_taskRunner.Push(PromiseFn());
        this.m_taskRunner.Start()