JS-异步函数链式调用2(精简版,推荐)

news/2024/6/18 21:10:53

基于《JS-异步函数链式调用》使用起来不是很方便直观,对此做一次优化,更符合使用的精简版:

//源码
function simpleChainedFn(){
    var localParam = arguments; //当前入参
    var firstFnArguments; //首节点的入参(数组格式)
    var chainLength = localParam.length; //除掉首节点入参,所有链条长度

    // 入参数据校验...
    for(i=0;i<localParam.length;i++){
        if(!localParam[i] || typeof localParam[i] !== "function"){
            // 如果当前是倒是第二个,则认为是首节点的入参;链条长度减1...
            if(i === localParam.length - 1){
                firstFnArguments = localParam[i];
                chainLength -= 1;
            }else{
                console.log("【error】链条参数有误!");
                return;
            }

        }
    }

    // 组合链条...
    var firstFn = (function combinationFn(index){
        var curFnIndex = index || 0; //当前函数索引
        var callBack; //当前函数参数回调

        // 如果存在下一条,则将下一条绑定为当前的回调...
        if(curFnIndex + 1 <  chainLength){
            callBack = arguments.callee(curFnIndex + 1);
        }

        var curFn = localParam[curFnIndex];
        if(curFn){
            if(callBack){
                curFn.callback = callBack;
            }
            return curFn;
        }else{
            return false;
        }

    })();

    // 启动链条 ...
    if(typeof firstFn === "function"){
        var suctnParam = "";
        if(firstFnArguments){
            for(var i = 0 ; i < firstFnArguments.length; i ++)
            {
                suctnParam += "firstFnArguments[" + i + "]" + (i === firstFnArguments.length - 1 ? "" : ",");
            }
        }
        eval("firstFn(" + suctnParam + ")");

    }
}

// 获取回调函数
function getCallbackFn(){
    return this.callback;
}

链条模板:

simpleChainedFn(函数1,函数2,....,函数n,[首节点入参1,首节点入参2,...首节点入参n]);

模板说明:
    1、支持多个函数自动扩展;
    2、如果最后一个参数是数组,则作为首节点调用时的入参;
    3、首节点入参个数会随着数组长度自动扩展;
    

函数模板:

function 函数名(入参1,入参2,...,入参n){
    var callback = getCallbackFn.call(arguments.callee);
    // TODO...
    

    if(callback && typeof callback === "function"){
        callback(入参1,入参2,...,入参n);
    }

}

模板说明:
    1、"var callback = getCallbackFn.call(arguments.callee);"尽量在函数体前边;    

实际运用
假设现在有3个需要同步执行的函数:fnA,fnB,fnC;
fnA的功能:将基数(入参1),乘上乘积(入参2),结果值和倒计时(入参3)传给fnB;
fnB的功能:进入倒计时,倒计时结束后,将入参乘上5,然后传给fnC;
fnC的功能:将参数打印出来;

// 组合链式关系 ...
simpleChainedFn(fnA,fnB,fnC,[2,10,5]);




// 将基数(入参1),乘上乘积(入参2),结果值和倒计时(入参3)传给fnB...
function fnA(base,multiplier,cDown){
    var callback = getCallbackFn.call(arguments.callee);

    console.log("【fnA】基数:" + base + ",乘积:" + multiplier + ",倒计时:" + cDown);
    var num = base * multiplier ;

    if(callback && typeof callback === "function"){
        console.log("【fnA】执行完毕,结果为:" + num + ",准备进入fnB。");
        callback(num,cDown); // 等价于fnB
    }

}

// 进入倒计时,倒计时结束后,将入参乘上5,然后传给fnC...
function fnB(base,cDown){
    var callback = getCallbackFn.call(arguments.callee);

    console.log("【fnB】基数:" + base + ",倒计时:" + cDown);
    var countDown = cDown;
    var tTout = setInterval(function(){
        console.log("【fnB】进入倒计时 -> " + --countDown + "s");
        if(countDown <= 0){
            console.log("【fnB】倒计数结束");
            countDown = -1;
            clearTimeout(tTout);

            var num = base * 5;

            if(callback && typeof callback === "function"){
                console.log("【fnB】执行完毕,结果为:" + num + ",准备进入fnC。");
                callback(num);// 等价于fnC
            }
        }
    },1000);
}

// 将参数打印出来;
function fnC(tArg){
    var callback = getCallbackFn.call(arguments.callee);

    console.log("【fnC】计算结果为:" + tArg);
    if(callback && typeof callback === "function"){
        callback();
    }

}

执行结果:

【FnA】基数:2,乘积:10,倒计时:5
【FnA】执行完毕,结果为:20,准备进入fnB。
【fnB】基数:20,倒计时:5
【fnB】进入倒计时 -> 4s
【fnB】进入倒计时 -> 3s
【fnB】进入倒计时 -> 2s
【fnB】进入倒计时 -> 1s
【fnB】进入倒计时 -> 0s
【fnB】倒计数结束
【fnB】执行完毕,结果为:100,准备进入fnC。
【fnC】计算结果为:100




http://www.niftyadmin.cn/n/3040002.html

相关文章

Node.js学习(3)----Server实例

这里使用Node.js实现一个最简单的Web服务器。 index.js var http require(http); http.createServer(function(req,res){res.writeHead(200,{Content-Type:text/plain});res.end(Hello Node.js\n); }).listen(8080,"127.0.0.1");console.log("Server start at…

怎么防止域名劫持

域名是网站的门户&#xff0c;对网站来说是一项重要的存在&#xff0c;可以说一旦域名出现问题&#xff0c;那么你的网站就有可能被找不到。所以域名安全直接关乎网站的安全访问&#xff0c;但是一旦域名出现问题&#xff0c;比如域名被劫持了&#xff0c;那么对于网站来说后果…

[转载]班主任带着学生打副本 每周学习成绩就是DKP(这篇太雷人了,转载保持)...

原文:http://bbs.ngacn.cc/read.php?tid2924677&fpage&forder_by&&page1 人们总是在不同的高度仰望着世界&#xff0c;而世界总是以不同的姿态展现在人们面前&#xff0c;无论你在什么地方&#xff0c;从事什么职业。用心去聆听&#xff0c;你会发现一切都会改…

反向 Ajax,第 3 部分: Web 服务器和 Socket.IO

简介 现今&#xff0c;用户都期待能够通过 Web 访问快速的动态访问应用。本 系列文章 向您展示如何使用 Reverse Ajax 技术来开发事件驱动的 Web 应用程序。反向 Ajax&#xff0c;第 1 部分&#xff1a;Comet 简介 介绍了 Reverse Ajax、轮询、流、Comet 和长轮询。在您了解了如…

注册域名需要注意的

很多人认为注册域名其实挺简单的&#xff0c;其实注册域名的过程中我们也有许多要注意的地方。域名的字符不一样&#xff0c;所代表的含义也就不一样。我们在注册成功后&#xff0c;还要进行域名解析这样域名注册才算真的成了。那么在注册域名的过程中有哪些事项需要我们注意呢…

常见的几种Flume日志收集场景实战

这里主要介绍几种常见的日志的source来源&#xff0c;包括监控文件型&#xff0c;监控文件内容增量&#xff0c;TCP和HTTP。 Spool类型 用于监控指定目录内数据变更&#xff0c;若有新文件&#xff0c;则将新文件内数据读取上传 在教你一步搭建Flume分布式日志系统最后有介绍此…

反向 Ajax,第 5 部分: 事件驱动的 Web 开发

简介 本 系列 文章向您展示如何使用反向 Ajax 技术开发事件驱动的 Web 程序。第 1 部分 介绍了反向 Ajax、轮询、流、Comet 和长轮询。第 2 部分 介绍了如何使用 WebSocket&#xff0c;还讨论了使用 Comet 和 WebSocket 的 Web 服务器的限制。第 3 部分 探讨了当您需要支持多个…

Node.js学习(4)----Node模块

1、什么是模块 开始编写Node应用之前&#xff0c;必须先学会Node的模块和包。模块和包是组成应用的基本单位。一个Node.js文件就是一个模块&#xff0c;这个文件可能是Javascript代码、JSON或者编译过的C/C扩展。 例如:simple.js var count0; exports.nextfunction(){return …