koa-compose簡單實現(xiàn)及使用的妙處
場景
今年的行情真的是非常的差,而且面試的時候卷的不行。前段時間,有個朋友去面了某大廠,竟然被問到了手寫一個koa-compose。那咱們今天就簡單的實現(xiàn)一個看看到底難不難。
面試官讓你實現(xiàn)一個場景:有一件衣服單價50元,買了num件,總和打了8折,然后運費是12元,算出買這num件衣服加上運費算上折扣需要多少錢?
首先需要實現(xiàn)三個函數(shù)
const express = (total) => {
return total + 12;
};
const discount = (total) => {
return total * 0.8;
};
const TShirtNum = (num) => {
return 50 * num;
};
TShirtNum代表num件衣服需要的費用,discount表示打了8折之后的費用,express表示算上運費的費用。
現(xiàn)在要求實現(xiàn)一個compose函數(shù),然后調(diào)用這個函數(shù),并把上面三個函數(shù)傳入compose函數(shù)中,最后計算出結(jié)果。比如
const sellTshirt = compose([TShirtNum, discount, express]); sellTshirt(100)
sellTshirt(100)會計算出最后的結(jié)果。如果要計算出最后的結(jié)果,就需要將TShirtNum計算出的結(jié)果傳給discount,然后discount計算出的結(jié)果傳給express。
此時我們可以使用reduce實現(xiàn)。MDN介紹reduce為:reduce() 方法對數(shù)組中的每個元素按序執(zhí)行一個由您提供的 reducer 函數(shù),每一次運行 reducer 會將先前元素的計算結(jié)果作為參數(shù)傳入,最后將其結(jié)果匯總為單個返回值。
第一次執(zhí)行回調(diào)函數(shù)時,不存在“上一次的計算結(jié)果”。如果需要回調(diào)函數(shù)從數(shù)組索引為 0 的元素開始執(zhí)行,則需要傳遞初始值。否則,數(shù)組索引為 0 的元素將被作為初始值 initialValue,迭代器將從第二個元素開始執(zhí)行(索引為 1 而不是 0)。
很顯然compose需要返回一個函數(shù)
const compose = (funcArr) => (startNum) => funcArr.reduce((pre, cur) => cur(pre), startNum)
一行代碼解決。startNum表示我們需要購買的數(shù)量,當做reduce的初始值,然后將上一次計算的結(jié)果傳給下一個函數(shù),相當于是TShirtNum計算的結(jié)果傳給discount, 也就是我們代碼中實現(xiàn)的cur(pre)。最后即可計算出結(jié)果。redux源碼就是這樣實現(xiàn)的??
koa-compose實現(xiàn)
現(xiàn)在面試官將這三個方法改造了一下。
const express = (total, next) => {
console.log("starting, express"); // 3
next(total + 12);
console.log("ending, express"); // 4
};
const discount = (total, next) => {
console.log("starting, discount"); // 2
next(total * 0.8);
console.log("ending, discount"); // 5
};
const TShirtNum = (num, next) => {
console.log("starting, TShirtNum"); // 1
next(15 * num);
console.log("ending, TShirtNum"); // 6
};
要求按照順序打印結(jié)果。同時會看到每個函數(shù)中都多了一個next方法。仔細觀察你會發(fā)現(xiàn),next其實就是調(diào)用下一個方法。我們用一個圖來表示:

下面我們用代碼實現(xiàn)一下
function compose(arr) {
let result;
return function (ctx) {
let dispatch = function (i, ctx) {
let fn;
if (i < arr.length) {
fn = arr[i];
}
if (i === arr.length) {
result = ctx;
return;
}
return fn(ctx, dispatch.bind(null, ++i));
};
dispatch(0, ctx);
return result;
};
}
const sellTshirt = compose([TShirtNum, discount, express]);
console.log(sellTshirt(100));
由于最后執(zhí)行的是sellTshirt(100),所以需要返回一個函數(shù)。在這個函數(shù)內(nèi)部定義一個dispatch方法,然后首次執(zhí)行傳入一個i為0,代表arr中的第一個函數(shù),執(zhí)行這個函數(shù)。在執(zhí)行這個函數(shù)的時候需要多傳入一個參數(shù)作為next, 而這個參數(shù)就是dispatch,傳入的時候,i遞增,代表arr中可以取下一個函數(shù)了。當執(zhí)行next的時候其實就是執(zhí)行dispatch。最后執(zhí)行的結(jié)果為:

其實就是用遞歸的思想去實現(xiàn)。大家可以去看下koa-compose的源碼基本上也就是這樣。
以上就是koa-compose簡單實現(xiàn)及使用的妙處的詳細內(nèi)容,更多關(guān)于koa-compose簡單實現(xiàn)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
如何解決安裝websocket還是報錯Cannot find module'ws&apos
這篇文章主要介紹了如何解決安裝websocket還是報Cannot find module'ws'問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
node.js中fs文件系統(tǒng)模塊的使用方法實例詳解
這篇文章主要介紹了node.js中fs文件系統(tǒng)模塊的使用方法,結(jié)合實例形式詳細分析了node.js fs文件系統(tǒng)模塊各種常見方法的基本使用技巧與相關(guān)操作注意事項,需要的朋友可以參考下2020-02-02
windows如何把已安裝的nodejs高版本降級為低版本(圖文教程)
這篇文章主要介紹了windows如何把已安裝的nodejs高版本降級為低版本,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
Nodejs 構(gòu)建Cluster集群多線程Worker threads
這篇文章主要為大家介紹了Nodejs 構(gòu)建Cluster集群多線程Worker threads示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
node.js中的http.response.removeHeader方法使用說明
這篇文章主要介紹了node.js中的http.response.removeHeader方法使用說明,本文介紹了http.response.removeHeader的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下2014-12-12

