首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >承诺重试设计模式

承诺重试设计模式
EN

Stack Overflow用户
提问于 2016-07-05 22:11:52
回答 20查看 116.8K关注 0票数 109

编辑

  1. 持续重试直到承诺解决为止的模式(使用delaymaxRetries)。
  2. 持续重试直到条件在结果上满足为止的模式(使用delaymaxRetries)。
  3. 具有无限重试的有效内存动态模式(delay提供)。

代码的#1.继续重试,直到承诺解决(对语言的任何改进社区等?)

代码语言:javascript
复制
Promise.retry = function(fn, times, delay) {
    return new Promise(function(resolve, reject){
        var error;
        var attempt = function() {
            if (times == 0) {
                reject(error);
            } else {
                fn().then(resolve)
                    .catch(function(e){
                        times--;
                        error = e;
                        setTimeout(function(){attempt()}, delay);
                    });
            }
        };
        attempt();
    });
};

使用

代码语言:javascript
复制
work.getStatus()
    .then(function(result){ //retry, some glitch in the system
        return Promise.retry(work.unpublish.bind(work, result), 10, 2000);
    })
    .then(function(){console.log('done')})
    .catch(console.error);

代码的#2继续重试,直到一个条件满足在then上的结果,以可重用的方式(条件是什么将改变)。

代码语言:javascript
复制
work.publish()
    .then(function(result){
        return new Promise(function(resolve, reject){
            var intervalId = setInterval(function(){
                work.requestStatus(result).then(function(result2){
                    switch(result2.status) {
                        case "progress": break; //do nothing
                        case "success": clearInterval(intervalId); resolve(result2); break;
                        case "failure": clearInterval(intervalId); reject(result2); break;
                    }
                }).catch(function(error){clearInterval(intervalId); reject(error)});
            }, 1000);
        });
    })
    .then(function(){console.log('done')})
    .catch(console.error);
EN

Stack Overflow用户

发布于 2022-06-16 18:52:04

这对我来说是完美的:

代码语言:javascript
复制
async wait(timeInMilliseconds: number, name?: string) {
    const messageSuffix = name ? ` => ${name}` : ""
    await this.logger.info(`Waiting for ${timeInMilliseconds} ms${messageSuffix}`).then(log => log())
    return new Promise<void>(resolve => setTimeout(resolve, timeInMilliseconds))
}

async waitUntilCondition(name: string, condition: () => boolean | Promise<boolean>, scanTimeInSeconds: number, timeoutInSeconds: number) {
    await this.logger.info(`Waiting until condition: name=${name}, scanTime: ${scanTimeInSeconds} s, timeout: ${timeoutInSeconds} s`).then(log => log())
    const timeoutInMillis = timeoutInSeconds * 1000
    return new Promise<void>(async (resolve, reject) => {
        const startTime = new Date().getTime()
        let completed = false
        let iteration = 0
        while (!completed) {
            if (iteration++ > 0) {
                const timingOutInSeconds = Math.round((timeoutInMillis - (new Date().getTime() - startTime)) / 1000.0)
                await this.wait(scanTimeInSeconds * 1000, `${name}, timing out in ${timingOutInSeconds} s`)
            }
            try {
                completed = await condition()
                if (completed) {
                    resolve()
                    return
                }
            } catch (error: any) {
                reject(error)
                throw error
            }
            const waitTimeMillis = new Date().getTime() - startTime
            if (waitTimeMillis > timeoutInMillis) {
                reject(`The condition '${name}' timed out. Time waited: ${waitTimeMillis / 1000} seconds`)
                return
            }
        }
    })
}
票数 0
EN
查看全部 20 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38213668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档