使用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是不准的了。这跟浏览器的事件循环机制有关系(挖了一个坑)。
本文探讨了在JavaScript中使用Promise和async/await替代传统while(true)循环的方法,通过具体示例展示了如何利用sleep函数实现定时任务,同时讨论了setTimeout和setInterval的精度问题及其与浏览器事件循环的关系。
297

被折叠的 条评论
为什么被折叠?



