1.組合函數即由若干個函數組合成一個新的函數,同時完成數據的傳遞
1>最簡單版本
這種方法實現的組合函數,需要我們指定函數的執行順序
/**第一種方法 */ function add(a, b) { return a + b; } function square(a) { return a * a; } function compose(fn1, fn2) { return (...args) => fn1(fn2(...args)); } console.log(compose(square, add)(1, 2));
2>升級版本
此種方法可以順序執行我們輸入的函數
/**第二種方法 可以按照順序執行*/
function compose2(mids) { return (...args) => { let ret = mids[0](...args); for (let i = 1; i < mids.length; i++) { ret = mids[i](ret); } return ret; } } console.log(compose2([add, square])(1, 2));
3>當我們的某些函數需要異步執行的時候,可以使用下面的方法,用next來完成函數的下一步操作 (類似於koa異步函數的實現過程)
思路:異步的實現需要借助Promise,函數必須返回一個Promise
function sleep() { return new Promise((resolve) => { setTimeout(() => { resolve(); }, 2000); }) } async function fn1(next) { console.log('fn1'); setTimeout(() => { console.log('fn1 settimeout'); }, 1000); await next(); console.log('end fn1'); } async function fn2(next) { console.log('fn2'); await sleep(); await next(); console.log('end fn2'); } async function fn3(next) { console.log('end fn3'); } function compose(mids) { return function () {//最終組合結果函數 //執行第0個 return dispatch(0); //需要返回Promise function dispatch(i) { let fn = mids[i]; if (!fn) { //執行任務結束 return Promise.resolve(); } return Promise.resolve(fn(function next() { return dispatch(i + 1); })); } } } compose([fn1, fn2, fn3])().then(() => console.log("任務執行結束"));
最終的執行結果是:
fn1
fn2
fn1 settimeout
end fn3
end fn2
end fn1