使用setInterval
而没有使用while(true)
主要还是为了练习Promise
和 async/await
的使用
(async function(){
/**
* s 休眠时长, 单位:秒
*/
function sleep(s){
s = s || 0;
s = parseInt(s) * 1000;
let now = +new Date();
let timer = null;
return new Promise((resolve, reject)=>{
timer = setInterval(()=>{
if( now + s < +new Date()){
clearInterval(timer);
resolve(true);
}
}, 10)
})
}
console.log(`start: ${new Date()}`);
await sleep(3); // 休眠3秒
console.log(`end : ${new Date()}`);
})()
PS:因为是通过setInterval
轮询,而任何通过轮询进行处理的问题,都会可能产生误差。
而实际上JS中setTimeout/setInterval的实现机制就存在误差, 请看下面的例子:
let start = new Date();
console.log(`start: ${start}`);
setTimeout(()=>{
console.log('This line will be log in 3 seconds?');
console.log(`end : ${new Date()}`);
}
, 3000);
while (true) {
if ((+start + 5000) < +new Date()) {
return;
}
}
上面这段代码中setTimeout并不是在3秒后执行的,如果理解了这句话,就知道为什么setTimeout是不准的了。这跟浏览器的事件循环机制有关系(挖了一个坑)。