乐趣区

关于javascript:串联执行N未知个函数

第一种形式,间接遍历循环:

这种形式最简略,要串联执行多个函数,能够遍历循环执行,代码如下:

// 1 
let a1 = function (next) {console.log("a1"); } 
let a2 = function (next) {console.log("a2"); } 
let a3 = function (next) {console.log("a3"); } 
let arr = [a1,a2,a3]; 
arr.forEach(e=>e());

第二种形式, 依照洋葱构造来结构代码构造,相似如图:

如何结构这样的代码呢,代码示例如下:

let a1 = function (next) {console.log("a1"); next()} 
let a2 = function (next) {console.log("a2"); next()} 
let a3 = function (next) {console.log("a3"); next()} 
let arr = [a1, a2, a3]; 
let a = arr.reduce((a, b) => {return () => b(a) },
    () => console.log("start")
); 
a();

察看源码,咱们在定义函数时为函数减少一个参数 next,next 是以后执行函数执行完后,下一个执行函数。

通过 reduce 函数的解决后,咱们失去了函数 a,函数 a 的函数函数体,咱们能够利用数学中的函数代入失去后果:

function a () {console.log("a3");
(function (next) {console.log("a2");
    (function (next) {console.log("a1");
        (() => console.log("start") )()} )()} )()} 

下面的代码除了用 reduce 之外咱们还能够应用循环来结构,代码如下:

let a1 = function (next) {console.log("a1"); next()} 
let a2 = function (next) {console.log("a2"); next()} 
let a3 = function (next) {console.log("a3"); next()} 
let arr = [a1, a2, a3]; 
let a = () => console.log("start"); 
for (let i = 0; i < arr.length; i++) { 
    let next = a; 
    a = ()=>{ arr[i](next) } 
} a();

a 函数最终失去的后果和下面是一样的,只是办法不一样而已。

除了循环和 reduce,咱们还能够应用递归,代码如下:


let a1 = function (next) {console.log("a1"); next()}
let a2 = function (next) {console.log("a2"); next()} 
let a3 = function (next) {console.log("a3"); next()} 
let arr = [a1, a2, a3]; 
var i = 0; 
function next() { var task = arr[i++]; // 取出函数数组里的下一个函数 
    if (!task) {
    // 如果函数不存在,
    return return; 
    } 
    task(next); // 否则, 执行下一个函数 
}
next();

递归调用原理也是相似结构一个回调函数,不过更趋向于流程化执行,更偏向于一边执行一边结构,而不是向下面两种形式,下面两种形式是先结构后执行。

浏览源码,咱们定义了一个 next 函数和以一个全局变量 i,i 来标记执行到哪一个函数了,next 调用标记着递归调用开始,每次执行 i 都会递增,而后从数组中取出中间件执行,中间件执行时传递进 next,反复进行下一个调用轮回。

以上便是串联执行 N(未知) 个函数多种形式,利用最多的就是 js 技术栈中的中间件,redux 的中间件,express 的中间件都是用的以上的办法,多操作,多思考,渺小改良每天提高一点点,心愿对你有所帮忙。

退出移动版