阅读 1196

js函数式编程 - retry函数

这是我参与更文挑战的第14天,活动详情查看更文挑战

这篇文章是来源很久之前了,当时还在第一家公司,和我当时的leader发生的一次沟通。

背景

当时leader让我创建一个retry函数,目的是为了执行某一个函数,当函数执行成功则返回正确的结果,如果执行失败则需要在1000ms内执行当前函数4次直到返回正确结果,如果1000ms内还没有返回结果,则需要返回错误提示信息。

在黑板面前思考然后写下来,当时写的乱七八糟的。

初始版本

假设随机函数计算的值大于80,我们就返回true,否则重新try。

var executeFunction = function() {
    var timespan = 250;
    var maxCount = 4;
    var executeCount = 0;
 
    var success = function() {
        console.log('success');
    }
 
    var fail = function() {
        console.log('fail');
    }
 
    return function returnFunction(callback) {
        setTimeout(function() {
            if (callback()) {
                return success();
            } else if (++executeCount < maxCount) {
                returnFunction(callback);
            } else {
                return fail();
            }
        }, timespan);
    }
}
 
var testFunction = function() {
    var date = new Date();
  	var returnValue = Math.random(0, 1) * 100; 
 
    console.log("execute testFunction: Date " + date.toString() + ". ms: " + date.getMilliseconds() );
  	console.info(returnValue)  
  
    if (returnValue > 80) {  
        return true;  
    }   
  
    return false;  
}
 
executeFunction()(testFunction);
复制代码

执行了三次,前两次都没有返回正确的值,最后一次返回正确的值。

屏幕录制2021-06-14 下午9.11.56.2021-06-14 21_14_35.gif
image.png

leader的本意【猜想】

其实在我们将代码书写在黑板上写过之后,当然没有完成。leader说当我看到你们写代码的时候,你们写代码是在做1+1=2的过程。

这个1+1=2的含义是什么呢?
写代码的时候上来就是一些不是关键的东西写出来了,例如1000ms,执行4次的条件在代码了写出来了。

image.png
如上图:我们其实将这个问题的分析走了一个逆向的思维,是先考虑了比较detail的问题,然后执行1+1最后生成最后的代码。

leader的本意应该如下【猜想】

leader的想法是让我们做f(x, y),让我们从上往下考虑。
image.png

/*retry*/  
var retry = function(functionName, retryCondition, retryConfig) {  
    if (typeof functionName != 'function') {  
        return "functionName should be function!";  
    }  
  
    if (typeof retryCondition != 'function') {  
        return "retryCondition should be function!";  
    }  
  
    if (typeof retryConfig != 'object') {  
        return "retryConfig should be object!";  
    } 
 
 
    retryConfig.retryTimeRange = retryConfig.retryTimeRange || 0;
    retryConfig.retryCount = retryConfig.retryCount || 1;
  
    var returnValue = functionName();  
    var retryIndex = 0;  
  
    if (!retryCondition(returnValue)) {  
        return returnValue;  
    } else {  
        var retryTimeSpan = retryConfig.retryTimeRange / retryConfig.retryCount;  
  
        (function retry() {  
            setTimeout(function() {  
                var returnValue = functionName();  
  
                if (!retryCondition(returnValue)) {  /*return true will try*/  
                    return returnValue;  
                } else if (++retryIndex < retryConfig.retryCount) {  
                    retry();  
                } else {  
                    console.info("fail returnvalue: " + returnValue);  
                    return returnValue;  
                }  
            }, retryTimeSpan);  
        })(functionName);  
    }  
}  
  
/*test*/  
var functionName1 = function() {  
    var returnValue = Math.random() * 100;  
  
    /*log innfo*/  
    var date = new Date();  
    console.info("execute testFunction: Date " + date.toString() + ". ms: " + date.getMilliseconds() );  
    console.info("returnvalue: " + returnValue);  
  
    return returnValue;  
}  
  
var retryCondition1 = function(returnValue) {  
    if (returnValue > 80) {  
        return false;  
    }   
  
    return true;  
}  
  
var retryConfig1 = {  
    retryTimeRange: 1000,  
    retryCount: 5  
}  
  
retry(functionName1, retryCondition1, retryConfig1);  
复制代码

我们看一下返回的结果(这里的测试是使用随机数返回值,如果随机数*100 > 80则返回值,如果retry时间到了还没有正确答案,则返回值并标明是错误的结果的),下面的三次返回第二次存在正确返回值,其他两次五次retry还是没有正确的返回值。

image.png
上面的结果是其实最后是使用函数式编程的组合函数的概念。但是和组合函数又不是很相同。但是核心都还是函数编程的思路。函数组合

文章分类
前端