原文:如何實現一個LazyManjavascript
實現一個LazyMan,能夠按照如下方式調用:java
LazyMan('Hank')
,輸出:面試
Hi, This is Hank!異步
LazyMan('Hank').sleep(5).eat('dinner')
,輸出:async
Hi, This is Hank!
// 等待5秒
Weak up after 10
Eat dinner ~post
LazyMan('Hank').eat('dinner').eat('supper')
,輸出測試
Hi, this is Hank!
Eat dinner ~
Eat supper ~this
LazyMan('Hank').sleepFirst(5).eat('supper')
,輸出code
// 等待5秒
Wake up after 5
Hi, this is Hank!
Eat supper對象
以此類推
eat
sleep
、sleepFirst
方法須要時異步的_LazyMan
eat
。sleep
、sleepFirst
異步方法採用Promise
和setTimeout
實現async wait
實現。每次調用都往隊列中加入方法,而後循環調用任務隊列,而循環中經過異步實現異步的方法,保證正確。class _LazyMan { constructor (name) { this.taskQueue = []; this.runTimer = null; this.sayHi(name); } run () { if (this.runTimer) { clearTimeout(this.runTimer); } this.runTimer = setTimeout(async () => { for (let asyncFun of this.taskQueue) { await asyncFun() } this.taskQueue.length = 0; this.runTimer = null; }) return this; } sayHi (name) { this.taskQueue.push(async () => console.log(`Hi, this is ${name}`)); return this.run(); } eat (food) { this.taskQueue.push(async () => console.log(`Eat ${food}`)); return this.run(); } sleep (second) { this.taskQueue.push(async () => { console.log(`Sleep ${second} s`) return this._timeout(second) }); return this.run(); } sleepFirst (second) { this.taskQueue.unshift(async () => { console.log(`Sleep first ${second} s`) return this._timeout(second); }); return this.run(); } async _timeout (second) { await new Promise(resolve => { setTimeout(resolve, second * 1e3); }) } } // 測試 var LazyMan = name => new _LazyMan(name) // lazyMan('Hank'); lazyMan('Hank').sleep(10).eat('dinner'); // lazyMan('Hank').eat('dinner').eat('supper'); // lazyMan('Hank').sleepFirst(5).eat('supper');