Be based on JS asynchronous function chain call It's not very convenient and intuitive to use, so it's better to optimize it for the simplified version:
//Source code function simpleChainedFn(){ var localParam = arguments; //Current participation var firstFnArguments; //Input parameter of the first node (array format) var chainLength = localParam.length; //Remove the input parameter of the first node and all chain lengths // Input parameter data verification for(i=0;i<localParam.length;i++){ if(!localParam[i] || typeof localParam[i] !== "function"){ // If it is the second, it is considered as the input parameter of the first node; the chain length is reduced by 1 if(i === localParam.length - 1){ firstFnArguments = localParam[i]; chainLength -= 1; }else{ console.log("[error]Wrong chain parameters!"); return; } } } // Combine chain var firstFn = (function combinationFn(index){ var curFnIndex = index || 0; //Current function index var callBack; //Current function parameter callback // If the next one exists, bind the next one as the current 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; } })(); // Start chain 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 + ")"); } } // Get callback function function getCallbackFn(){ return this.callback; }
Chain template:
Simplechainedfn (function 1, function 2,..., function n, [first node in parameter 1, first node in parameter 2,... First node in parameter n]); Template description: 1. Support automatic extension of multiple functions; 2. If the last parameter is an array, it is used as the input parameter when the first node is called; 3. The number of input parameters of the first node will automatically expand with the array length;
Function template:
Function function name ({input parameter}){ var callback = getCallbackFn.call(arguments.callee); // TODO... if(callback && typeof callback === "function"){ callback({in parameter}); } } Template description: 1. To avoid closure, "var callback = getcallbackfn. Call (arguments. Call);" should be in front of the function body;
Practical application
Suppose there are three functions that need to be executed synchronously: fnA, fnB, fnC;
Function of fnA: multiply the cardinality (in parameter 1), product (in parameter 2), and pass the result value and countdown (in parameter 3) to fnB;
Function of fnB: enter the countdown, after the countdown, multiply the input parameter by 5, and then pass it to fnC;
Function of fnC: print out parameters;
// Combined chain relationship simpleChainedFn(fnA,fnB,fnC,[2,10,5]); // Pass the radix (in parameter 1), product (in parameter 2), result value and countdown (in parameter 3) to fnB function fnA(base,multiplier,cDown){ var callback = getCallbackFn.call(arguments.callee); console.log("[fnA]Cardinal number:" + base + ",Product:" + multiplier + ",Count down:" + cDown); var num = base * multiplier ; if(callback && typeof callback === "function"){ console.log("[fnA]After execution, the result is:" + num + ",Ready to enter fnB. "); callback(num,cDown); // Equivalent to fnB } } // Enter the countdown, after the countdown, multiply the input parameter by 5, and then pass it to fnC function fnB(base,cDown){ var callback = getCallbackFn.call(arguments.callee); console.log("[fnB]Cardinal number:" + base + ",Count down:" + cDown); var countDown = cDown; var tTout = setInterval(function(){ console.log("[fnB]Enter countdown -> " + --countDown + "s"); if(countDown <= 0){ console.log("[fnB]End of countdown"); countDown = -1; clearTimeout(tTout); var num = base * 5; if(callback && typeof callback === "function"){ console.log("[fnB]After execution, the result is:" + num + ",Ready to enter fnC. "); callback(num);// Equivalent to fnC } } },1000); } // Print out the parameters; function fnC(tArg){ var callback = getCallbackFn.call(arguments.callee); console.log("[fnC]The calculation results are as follows:" + tArg); if(callback && typeof callback === "function"){ callback(); } }
Execution result:
[FnA] base: 2, product: 10, Countdown: 5 [FnA] is completed, the result is: 20, ready to enter fnB. [fnB] base: 20, Countdown: 5 [fnB] enter Countdown - > 4S [fnB] enter Countdown - > 3S [fnB] enter Countdown - > 2S [fnB] enter Countdown - > 1s [fnB] enter Countdown - > 0s [fnB] end of countdown [fnB] is completed, the result is: 100, ready to enter fnC. [fnC] calculation result: 100