如何實現一個 LazyMan?
網上看到一道 JavaScript 筆試題,感覺還挺有意思的,在此記錄一番。
考察知識點:閉包 ,事件輪詢機制 ,鏈式呼叫 ,佇列
實現一個LazyMan,可以按照以下方式呼叫: 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 以此類推。 複製程式碼
下面是 ES6 的實現方式,如果用 ES5 來寫要在維護this
方面多寫一些程式碼。
class _LazyMan { constructor(name) { this.tasks = []; const task = () => { console.log(`Hi! This is ${name}`); this.next(); } this.tasks.push(task); setTimeout(() => {// 把 this.next() 放到呼叫棧清空之後執行 this.next(); }, 0); } next() { const task = this.tasks.shift(); // 取第一個任務執行 task && task(); } sleep(time) { this._sleepWrapper(time, false); return this;// 鏈式呼叫 } sleepFirst(time) { this._sleepWrapper(time, true); return this; } _sleepWrapper(time, first) { const task = () => { setTimeout(() => { console.log(`Wake up after ${time}`); this.next(); }, time * 1000) } if (first) { this.tasks.unshift(task);// 放到任務佇列頂部 } else { this.tasks.push(task);// 放到任務佇列尾部 } } eat(name) { const task = () => { console.log(`Eat ${name}`); this.next(); } this.tasks.push(task); return this; } } function LazyMan(name) { return new _LazyMan(name); } 複製程式碼
吐槽一下,最近想換工作,一直在準備面試,複習的時候感覺前端能考到的知識點真是多啊。
參考: https://zhuanlan.zhihu.com/p/22387417