摘要:前言之前在掘金上到一篇文章關(guān)于微信面試的文章,其中提到了手動(dòng)實(shí)現(xiàn)的問(wèn)題。看起來(lái)好像挺有趣的,我們來(lái)分析以下分析首先我們看到例子有幾個(gè)特點(diǎn),一個(gè)是我們調(diào)用的時(shí)候不需要用到關(guān)鍵字,這意味著我們需要使用工廠函數(shù)另一個(gè)是要我們實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用。
前言
之前在掘金上到一篇文章關(guān)于微信面試的文章,其中提到了手動(dòng)實(shí)現(xiàn)Lazyman的問(wèn)題。剛開(kāi)始
看到Lazyman我是一臉懵逼的,這是什么鬼,后來(lái)查了查了一下,才發(fā)現(xiàn),其實(shí)就是手動(dòng)實(shí)現(xiàn)
以下功能:
實(shí)現(xiàn)一個(gè)LazyMan,可以按照以下方式調(diào)用: LazyMan(“Hank”)輸出: Hi! This is Hank! ? LazyMan(“Hank”).sleep(10).eat(“dinner”)輸出 Hi! This is Hank! //等待10秒.. Wake up after 10 Eat dinner~ ? LazyMan(“Hank”).eat(“dinner”).eat(“supper”)輸出 Hi This is Hank! Eat dinner~ Eat supper~ ? LazyMan(“Hank”).sleepFirst(5).eat(“supper”)輸出 //等待5秒 Wake up after 5 Hi This is Hank! Eat supper ? 以此類(lèi)推。
看起來(lái)好像挺有趣的,我們來(lái)分析以下
分析首先我們看到例子有幾個(gè)特點(diǎn),一個(gè)是我們調(diào)用Lazyman的時(shí)候不需要用到new關(guān)鍵字,這意味著我們需要使用工廠函數(shù);另一個(gè)是要我們實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用。
我們看到LazyMan(“Hank”).eat(“dinner”).eat(“supper”)這樣的形式,無(wú)疑是鏈?zhǔn)秸{(diào)用了;還有一個(gè)難點(diǎn)就是 LazyMan(“Hank”).sleepFirst(5).eat(“supper”)
當(dāng)存在sleepFirst時(shí),我們還要先等待一段時(shí)間,然后再開(kāi)始報(bào)名字,這就說(shuō)明sleepFirst優(yōu)先級(jí)更高,不管何時(shí)注冊(cè),都要第一個(gè)執(zhí)行,仔細(xì)想想
有什么可以實(shí)現(xiàn)這個(gè)呢?明顯我們需要一個(gè)任務(wù)隊(duì)列,而且sleepFirst放在最前面,然后等所有任務(wù)都安排好了,才開(kāi)始執(zhí)行任務(wù)隊(duì)列
恩?那說(shuō)明執(zhí)行任務(wù)不能緊跟在插入任務(wù)全程的后面,那我們見(jiàn)他們分進(jìn)兩個(gè)事件隊(duì)列就好了,這就需要借助setTimeout函數(shù)了;
除此之外,一個(gè)任務(wù)完成了,我們?cè)趺赐ㄖ蝿?wù)隊(duì)列去取下一個(gè)任務(wù)呢?這就需要一個(gè)尾調(diào)用。
經(jīng)過(guò)上面的分析,我們可以開(kāi)始編碼了:
首先,我們先寫(xiě)工廠函數(shù)
function Lazyman ( name ) { return new _Lazyman ( name ); }
接著我們開(kāi)始實(shí)現(xiàn)Lazyman:
constructor ( name ) { this.tasks = [];//設(shè)置任務(wù)隊(duì)列 let task = (name => () => { console.log ( `Hi! This is ${name} !` ); this.next (); }) ( name ); this.tasks.push ( task ); //通過(guò)settimeout的方法,將執(zhí)行函數(shù)放入下一個(gè)事件隊(duì)列中,從而達(dá)到先注冊(cè)事件,后執(zhí)行的目的 setTimeout ( () => { this.next (); }, 0 ); } //尾調(diào)用函數(shù),一個(gè)任務(wù)執(zhí)行完然后再調(diào)用下一個(gè)任務(wù) next () { let task = this.tasks.shift (); task && task (); } eat ( food ) { let task = (food => () => { console.log ( `Eat ${food}` ); this.next (); }) ( food ); this.tasks.push ( task ); return this; } sleep ( time ) { let task = (time => () => { setTimeout ( () => { console.log ( `Wake up after ${time} s!` ); this.next (); }, time * 1000 ) }) ( time ); this.tasks.push ( task ); return this; } sleepFirst ( time ) { let task = (time => () => { setTimeout ( () => { console.log ( `Wake up after ${time} s!` ); this.next (); }, time * 1000 ) }) ( time ); this.tasks.unshift ( task );//sleepFirst函數(shù)需要最先執(zhí)行,所以我們需要在任務(wù)隊(duì)列前面放入,然后再執(zhí)行后面的任務(wù) return this; } }
通過(guò)上面的步驟,我們就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的Lazyman了
改進(jìn)上面明明實(shí)現(xiàn)了一個(gè)Lazyman了呀,還有什么可以改進(jìn)的?當(dāng)然有,如果我們調(diào)用eat的時(shí)候,想輸出的是Eaaaaaaaaaat ${food}!!!!,然后輸出好飽啊好飽啊
這意味著每次改變,我們都要去修改eat這個(gè)函數(shù),這就耦合度太高了,這時(shí)候,我們可以采用發(fā)布訂閱的方式,在調(diào)用eat的時(shí)候,我們注冊(cè)一個(gè)監(jiān)聽(tīng)函數(shù),然后當(dāng)任務(wù)
執(zhí)行的時(shí)候再發(fā)布這個(gè)事件,讓對(duì)應(yīng)的監(jiān)聽(tīng)函數(shù)執(zhí)行,這樣就實(shí)現(xiàn)了解耦了
一個(gè)小小的Lazyman,竟然有如此多的考點(diǎn),是在讓人受益匪淺,當(dāng)然,Lazyman還可以使用promise的方式實(shí)現(xiàn),當(dāng)然實(shí)現(xiàn)一個(gè)手寫(xiě)的Promise實(shí)在有點(diǎn)難(逃),有機(jī)會(huì)再用promise
實(shí)現(xiàn)一次哈
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/88231.html
摘要:只需要返回對(duì)象本身就可以了。這里只實(shí)現(xiàn)一個(gè)示例實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用從隊(duì)列頭部插入最后一步封裝還有一個(gè)大家可以來(lái)試一試。如果有想法的話(huà)歡迎提出大家交流一下 ES5實(shí)現(xiàn)LazyMan lazyman主要原理是: 需要一個(gè)隊(duì)列保存將要用到的事件 利用閉包將事件保存至隊(duì)列中 創(chuàng)建一個(gè)中間件next用來(lái)觸發(fā)事件 鏈?zhǔn)秸{(diào)用 使用lazyman需要實(shí)現(xiàn)的場(chǎng)景: LazyMan(Tom); // my n...
摘要:實(shí)現(xiàn)一個(gè),可以按照以下方式調(diào)用輸出輸出等待秒輸出輸出等待秒以此類(lèi)推。這是典型的流程控制,問(wèn)題的關(guān)鍵是如何實(shí)現(xiàn)任務(wù)的順序執(zhí)行。 實(shí)現(xiàn)一個(gè)LazyMan,可以按照以下方式調(diào)用: LazyMan(Hank)輸出: Hi! This is Hank! LazyMan(Hank).sleep(10).eat(dinner)輸出 Hi! This is H...
摘要:實(shí)現(xiàn)一個(gè),可以按照以下方式調(diào)用輸出輸出等待秒輸出輸出等待秒以此類(lèi)推。這是典型的流程控制,問(wèn)題的關(guān)鍵是如何實(shí)現(xiàn)任務(wù)的順序執(zhí)行。 實(shí)現(xiàn)一個(gè)LazyMan,可以按照以下方式調(diào)用: LazyMan(Hank)輸出: Hi! This is Hank! LazyMan(Hank).sleep(10).eat(dinner)輸出 Hi! This is H...
摘要:實(shí)現(xiàn)一個(gè),可以按照以下方式調(diào)用輸出輸出等待秒輸出輸出等待秒以此類(lèi)推。這是典型的流程控制,問(wèn)題的關(guān)鍵是如何實(shí)現(xiàn)任務(wù)的順序執(zhí)行。 實(shí)現(xiàn)一個(gè)LazyMan,可以按照以下方式調(diào)用: LazyMan(Hank)輸出: Hi! This is Hank! LazyMan(Hank).sleep(10).eat(dinner)輸出 Hi! This is H...
閱讀 1354·2021-09-10 10:51
閱讀 2829·2019-08-30 15:54
閱讀 3367·2019-08-29 17:11
閱讀 926·2019-08-29 16:44
閱讀 1391·2019-08-29 13:47
閱讀 1086·2019-08-29 13:47
閱讀 1485·2019-08-29 12:23
閱讀 1038·2019-08-28 18:18