JS重试函数几次,看看它是否返回true

JS Retry function several times to see if it returns true

本文关键字:是否 true 返回 几次 函数 重试 JS      更新时间:2023-10-15

如果函数返回true或false ,我正在寻找一种更好的重试方法

   function foo() { // 
        var tabList = window.content.document.getElementById('compTabs') // this might be null if page is not loaded and further code wont work
        if (!tabList) { // stop here if tab list is null
            return false;
        }
    // continue and finish function
        }

// this is a loop that will go trough an array and this check needs to happen for each element of the array 
for (var i; i < loopLenght; i++) {
    // This is the actual code nothing else happens here.
        if ( !foo() ) {
            // try again
            if ( !foo() ) {
                // try one more time
                if ( !foo() ) {
                    console.log('Failed')
                }
            }
        }
   // a lot more code coming here that should only run one per iteration
}

我只是在寻找一种更好、更干净的方式来编写上面的代码。

var retries = 5;
var success = false;
while (retries-- > 0 && !(success = foo())) {}
console.log(success);

这里,retries--在每次循环迭代时递减计数,success = foo()执行foo()并将结果保存到success中。

如果retries命中0success变为true,则循环停止。不需要循环体。

警告:如果foo()是异步函数,这将不起作用

你在浏览器中吗?(与节点等相对)它是否必须具体重试N次?

while (!condition) { }

但这会阻碍你前进。

如果你想投票。。。

function whileConditionNotMet()
{
   if (!condition) {
       setTimeout(whileConditionNotSet, 1000);
       return false;
   }
   // Condition met
   // ...
   return true;
}

你可以通过增加一个静态变量来限制它的检查次数:

function whileConditionNotMet()
{
   if ( typeof whileConditionNotMet.counter == 'undefined' ) {
       whileConditionNotMet.counter = 0;
   }
   if (whileConditionNotMet.counter++ > 10) {
       // Timeout
       // ...
       return false;
   }
   if (!condition) {
       setTimeout(whileConditionNotSet, 1000);
       return false;
   }
   // Condition met
   // ...
   return true;
}

var counter = 0;
while (!condition && counter++ < 10) { }
async function Retry( action, retryInterval = 5000, maxAttemptCount = 3 )
{
    const exceptions = [];
    for ( let attempted = 0 ; attempted < maxAttemptCount ; attempted++ )
    {
        try
        {
            if ( attempted > 0 )
                await sleep( retryInterval );
            return action( );
        }
        catch ( e )
        {
            exceptions.push( e );
        }
    }
    return exceptions;
}
function sleep( ms ) { return new Promise( resolve => setTimeout( resolve, ms ) ); }

使用:

Retry( function( ) { return 534 * 9 } ).then( (result) => { console.log( result ); } );
//retry 3 times with 5s interval
Retry( function( ) { throw "Exception" } ).then( (result) => { console.log( result ); } );
//retry 5 times with a 2s interval
Retry( function( ) { throw "Exception" }, 2000, 5 ).then( (result) => { console.log( result ); } );

看看我写了什么:

// -------------- RETRIES CLASS 151118 -------------------
// executeFunction     - Returns true if success, false otherwise
// limitRetries        - max number of retries
// sleepInBetweenMilli - the delay in millis between one retry to another
    function Retrier(executeFunction, limitRetries, sleepInBetweenMilli, successCallback, failCallback) {
        this.executeFunction = executeFunction;
        this.limitRetries = limitRetries;
        this.sleepInBetweenMilli = sleepInBetweenMilli;
        this.successCallback = successCallback;
        this.failCallback = failCallback;
        this.thisRetry = 1;
        var RetrierObjectThis = this;
        function doCycle() {
            var result = RetrierObjectThis.executeFunction();
            if (result == true) {
                RetrierObjectThis.successCallback();
            } else {
                if (RetrierObjectThis.thisRetry >= RetrierObjectThis.limitRetries) {
                    RetrierObjectThis.failCallback();
                } else {
                    RetrierObjectThis.thisRetry++;
                    setTimeout(doCycle, RetrierObjectThis.sleepInBetweenMilli);
                }
            }
        } 
        doCycle();
    }