const chainAsync = fns => { let curr = 0 ; const next = (...args) => fns[curr++](next,...args); //执行fns[0](next) : next是一个闭包,包着fns 和 curr ,其中curr只有在next执行的时候才确定fns[curr++]中curr是多少,知识点(函数定义和执行) //fns[1](next) : 执行的是fns[0]的next , next()执行时,curr为1 //fns[2](next) : 执行的时fns[1]的next , next()执行时,curr为2 next();//执行fns[0](next) } //fns :的每个元素[fn1,fn2,fn3,...] //每个元素接受的第一个参数是next,如fn1接受的第一个参数是next函数(...args) => fns[curr++](next,...args) 。由于这时候curr是1 在fn1内执行next就是执行fn2 //同理fn2接收的第一个参数也是next函数(...args) => fns[curr++](next,...args)。由于这时候curr是2 在fn2内执行next就是执行fn3 //后面同理,可见,每次执行next之后,curr才加一,到下一次再执行next的时候,curr是之前的值+1 //这就是闭包的魅力,不但可以缓存curr的值,还可以改变curr的值,到下次再执行时,curr是不同的值 //闭包中缓存的curr是指针?还是基本类型值?还是引用类型? curr是基本类型值,而缓存curr的是一个引用类型 {curr:0} 变量对象 //这里用了命令模式和闭包 : next是一个命令(宏),lambda,匿名函数,闭包 //命令模式就是一个匿名函数包着一个执行的函数 : 如 (fn)=>fn() //闭包(函数)可以缓存一些变量(类似C++的静态变量,直到程序结束才销毁),这里闭包(函数)缓存的变量就如静态变量,只有这个闭包(函数)被销毁这些缓存的变量才被销毁 // chainAsync([next=>{ // console.log(‘开始‘); // next(‘haha‘);//执行下一个函数fns[1](next,‘haha‘) // },(next,msg) =>{ // console.log(msg); // next();//执行下一个函数fns[2]() // },()=>console.log(‘end‘)]); //class实现 class ChainAsync{ constructor(fns){ this.fns = fns; this.curr = 0; this.next = this.next.bind(this); // this.next = (...args) => this.fns[this.curr++](this.next,...args); //也可以 } next(...args){ this.fns[this.curr++](this.next,...args); } } // const fn1 = (next) => console.log(‘开始‘) || next(‘fn2请接收‘);//执行fn2(next,‘fn2请接收‘) 这里next就是(next,‘fn2请接收‘)=>fn2(next,‘fn2请接收‘) // const fn2 = (next,msg) =>console.log(msg); //输出‘fn2请接收‘ // const chain = new ChainAsync([fn1,fn2]); // chain.next(); //输出: //开始 //fn2请接收