乙個有味道的函式

2022-02-08 17:48:20 字數 3388 閱讀 1917

最近想到了乙個自認為很有意思的面試題

如何實現乙個compose函式。

函式接收數個引數,引數均為function型別,右側函式的執行結果將作為左側函式執行的引數來呼叫。

1 compose(arg => `$%`, arg => arg.tofixed(2), arg => arg + 10)(5) //

15.00%

2 compose(arg => arg.tofixed(2), arg => arg + 10)(5) //

15.00

3 compose(arg => arg + 10)(5) //

15

執行結果如上述**,有興趣的同學可以先自己實現一下再來看後續的。

大致的思路為:

獲取所有的引數

呼叫最後乙個函式,並接收返回值

如果沒有後續的函式,返回資料,如果有,將返回值放入下乙個函式中執行

所以這種情況用遞迴來實現會比較清晰一些

1

function

compose (...funcs)

10 }

這樣,我們就實現了上述的compose函式。

真是可喜可賀,可喜可賀。

本文完。

好了,如果現實生活中開發做需求也是如此爽快不做作就好了,但是,產品總是會來的,需求總是會改的。

我們現在有如下要求,函式需要支援promise物件,而且要相容普通函式的方式。

示例**如下:

1

//為方便閱讀修改的排版

2compose(

3 arg => new promise((resolve, reject) =>

4 settimeout(_ =>

5 resolve(arg.tofixed(2)),

6 10007)

8),9 arg => arg + 10

10 )(5).then(data =>)

我們有如下**呼叫,對tofixed函式的呼叫新增1000ms的延遲。讓使用者覺得這個函式執行很慢,方便下次優化

所以,我們就需要去修改compose函式了。

我們之前的**只能支援普通函式的處理,現在因為新增了promise物件的原因,所以我們要進行如下修改:

首先,非同步函式改為同步函式是不存在的readfile/readfilesync這類除外。

所以,最簡單的方式就是,我們將普通函式改為非同步函式,也就是在普通函式外包一層promise

1

function

compose (...funcs) )16}

17}1819

//判斷引數是否為`promise`

20function

ispromise (pro)

2324

//將引數轉換為`promise`

25function

promiseify (pro)

我們針對compose**的改動主要是集中在這幾處:

compose的返回值改為了promise物件,這個是必然的,因為內部可能會包含promise引數,所以我們一定要返回乙個promise物件

將各個函式執行的返回值包裝為了promise物件,為了統一返回值。

處理函式返回值,監聽thencatch、並將resolvereject傳遞了過去。

現在,我們又得到了乙個新的需求,我們想要在其中某些函式執行中跳過部分**,先執行後續的函式,等到後續函式執行完後,再拿到返回值執行剩餘的**:

1

compose(

2 data => new promise((resolve, reject) => resolve(data + 2.5)),

3 data => new promise((resolve, reject) => resolve(data + 2.5)),

4 async function c (data, next) ,

12 (data, next) => new promise((resolve, reject) =>%`)

16 }).catch(reject) //

先執行後續的**

17}),

18function d (data)

19 )(15).then(console.log) //

0.45%

拿到需求後,陷入沉思。。。

好好地順序執行**,突然就變成了這個鳥樣,隨時可能會跳到後邊的函式去。

所以我們分析這個新需求的效果:

我們在函式執行到一半時,執行了nextnext的返回值為後續函式的執行返回值。

也就是說,我們在next中處理,直接呼叫佇列中的下乙個函式即可;

然後監聽thencatch**,即可在當前函式中獲取到返回值;

拿到返回值後就可以執行我們後續的**。

然後他的實現呢,也是非常的簡單,我們只需要修改如下**即可完成操作:

1

//在這裡會強行呼叫`exec`並傳入引數2//

而`exec`的執行,則意味著`funcs`集合中又乙個函式被從佇列中取出來

3 promiseify(func(arg, arg => exec(arg)))

也就是說,我們會提前執行下乙個函式,而且下乙個函式的then事件註冊是在我們當前函式內部的,當我們拿到返回值後,就可以進行後續的處理了。

而我們所有的函式是存放在乙個佇列裡的,在我們提前執行完畢該函式後,後續的執行也就不會再出現了。避免了乙個函式被重複執行的問題。

如果看到這裡已經很明白了,那麼恭喜,你已經了解了實現koajs最核心的**:

中介軟體的實現方式洋蔥模型

想必現在整個函式周遭散發著洋蔥的味道。

koa-compose

1.0,普通函式

2.0,promise函式

3.0,支援洋蔥模型

乙個函式作為另乙個函式的引數

函式的作為變數分裝到另一函式裡面 上面的函式是求乙個定義域能被3正處的數,首先可以想到的是0到100之間內能被3整除的數吧。這個應該很簡單,如下。這裡可以思考的是某個定義域,也就是說上面的i 0和i 100都應該是不確定的值,也就是變數,現在可以定義乙個函式,function checkout st...

乙個openGL的函式

最近挺忙很久沒寫東西。目前在寫一些opengl的東西,對於這個在3年前接觸過但是沒學好的語言一直耿耿於懷,其實很喜歡opengl。而且最近也沒事就一直開始寫著,寫opengl檢視模型的時候其實很重要的乙個東西就是它內部的矩陣棧。所以寫了乙個函式,專門用來輸出日誌,我自己覺的挺好用。這個函式的作用是專...

乙個高ai的分頁函式和乙個url函式

aidu ad 這個分頁 函式非常高只能的 看看就知道了 function ppage total,page,e page 15,e block 10,url color totalpage ceil total e page 頁面數目 p block ceil totalpage e block ...