題目:紅燈三秒亮一次,綠燈兩秒亮一次,黃燈一秒亮一次;如何讓三個燈不斷交替重復亮燈?三個亮燈函數已經存在:
function red(){
console.log('red - ', new Date());
}
function green(){
console.log('green - ', new Date());
}
function yellow(){
console.log('yellow - ', new Date());
}
1. callback實現
function loop(){
setTimeout(function(){
red();
setTimeout(function(){
green();
setTimeout(function(){
yellow();
loop();
}, 1000)
}, 2000)
}, 3000);
}
loop();
2. Promise實現
返回Promise對象的通用亮燈函數
function tic(timer, callback){
return new Promise(function(resolve, reject){
setTimeout(function(){
callback();
resolve();
}, timer)
})
}
var promise = new Promise(function(resolve, reject){ resolve() });
function loop(){
promise.then(function(){
return tic(3000, red);
}).then(function(){
return tic(2000, green);
}).then(function(){
return tic(1000, yellow);
}).then(function(){
loop();
})
}
loop();
3. Generator實現
function* light(){
yield tic(3000, red);
yield tic(2000, green);
yield tic(1000, yellow);
}
function loop(iterator, gen){
var result = iterator.next();
if (result.done) {
loop(gen(), gen)
} else {
result.value.then(function(){
loop(iterator, gen)
})
}
};
loop(light(), light);
4. async, await實現
(async function (){
while(true){
await tic(3000, red);
await tic(2000, green);
await tic(1000, yellow);
}
})();
5. 改進版的可擴展callback實現
function light(func, timer){
return function(callback){
setTimeout(function(){
func();
callback();
}, timer)
};
}
function queue(funcs){
(function next(){
if (funcs.length > 0){
var f = funcs.shift();
f(next)
}
})();
}
function loop(){
queue([
light(red, 3000),
light(green, 2000),
light(yellow, 1000),
loop
])
}
loop();
總結
- 最簡單的callback實現,當有更多個函數時,會導致回調地獄,代碼慘不忍睹,但經過封裝后,也可進行方便的擴展。
- Promise實現中規中矩
- Generator實現中包含了一個通用的Generator順序執行函數
- 最愛async, await實現