工具函数1:重复执行函数

283 阅读1分钟

重复执行函数

code

function isPromise<T>(val: unknown): val is () => Promise<T> {
    return (val !== undefined && val !== null) && typeof val === 'function' && typeof (<{ then?: unknown }>val)?.then === 'function' && typeof (<{ catch?: unknown }>val)?.catch === 'function'
}


export function createAutoTimer<T = unknown, E = unknown>(
    fn: () => Promise<T> | T,           //自动执行函数
    stopTrigger: (t: T) => boolean,     //检测是否需要停止的函数
    timeout = 5000,                     //间隔
    immediate = false,                  //是否立即执行一次
    autoClearTimerOnError = true,       //报错时是否停止自动执行
    onError?: (e: E) => void,           //报错时回调
) {
    let timer = -1;

    let wrapfn = <() => Promise<T>><unknown>null

    if (isPromise<T>(fn)) {
        wrapfn = fn
    } else {
        wrapfn = () => new Promise<T>((resolve) => {
            resolve(fn())
        })
    }

    const excutor = (immediate: boolean) => {
        timer = <number>(<unknown>setTimeout(
            () => {
                wrapfn().then((t) => {

                    if (stopTrigger(t)) {
                        clearTimeout(timer)
                    } else {
                        excutor(false)
                    }

                }).catch((e: E) => {
                    if (autoClearTimerOnError) clearTimeout(timer)
                    onError?.(e)
                })
            }
            , immediate ? 0 : timeout
        ));
    };

    excutor(immediate);

    return { cancel: () => clearTimeout(timer) }
}

ts playground demo

test2.gif