有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。
使用更好的DX实现更安全的异步睡眠
我使用睡眠进行调试。。。我忘了用wait太多次了。让我挠头。我在写下面的实时片段时忘记使用await。。。不再!
如果您在1毫秒内运行了两次,下面的睡眠功能会提醒您。如果您确定使用了await,它还支持传递一个相当的参数。它不会投掷,因此可以安全地用作睡眠的替代品。享受
是的,实时片段中有一个JavaScript版本。
// Sleep, with protection against accidentally forgetting to use await
export const sleep = (s: number, quiet?: boolean) => {
const sleepId = 'SLEEP_' + Date.now()
const G = globalThis as any
if (G[sleepId] === true && !quiet) {
console.error('Did you call sleep without await? use quiet to hide msg.')
} else {
G[sleepId] = true
}
return new Promise((resolve) => {
!quiet && setTimeout(() => {
delete G[sleepId]
}, 1)
setTimeout(resolve, (s * 1000) | 0)
})
}
//睡眠,防止意外忘记使用等待常量睡眠=(s,安静)=>{constsleepId='SLEEP_'+Date.now()const G=全局此if(G[sleepId]==true&&!quiet){console.error('您是否在没有等待的情况下调用sleep?使用quiet隐藏消息。')}其他{G[sleepId]=真}return new Promise((resolve)=>{!quiet&&setTimeout(()=>{删除G[sleepId]}, 1)setTimeout(解析,(s*1000)|0)})}常量main=async()=>{console.log('休眠1秒…')等待睡眠(1)console.log('使用等待的目标…')睡眠(99)睡眠(99)等待睡眠(1,true)console.log(“开发人员快乐!”)}main()
与公认更容易阅读的相比:
const sleep = (s: number) =>
new Promise((p) => setTimeout(p, (s * 1000) | 0))
可以使用带有递增较大值的闭包调用setTimeout()。
var items = ['item1', 'item2', 'item3'];
function functionToExecute(item) {
console.log('function executed for item: ' + item);
}
$.each(items, function (index, item) {
var timeoutValue = index * 2000;
setTimeout(function() {
console.log('waited ' + timeoutValue + ' milliseconds');
functionToExecute(item);
}, timeoutValue);
});
结果:
waited 0 milliseconds
function executed for item: item1
waited 2000 milliseconds
function executed for item: item2
waited 4000 milliseconds
function executed for item: item3
如果您真的想完全阻塞主线程并防止事件循环从事件队列中拉出,那么这里有一个很好的方法可以做到这一点,而不需要创建任何函数、新的Date对象或泄漏任何变量。我知道这个愚蠢的问题已经有一百万个答案了,但我没有看到有人使用这个精确的解决方案。这仅适用于现代浏览器。
警告:这不是你会投入生产的东西。它只是有助于理解浏览器事件循环。它可能对任何测试都没有用处。它不像一个正常的系统睡眠函数,因为JavaScript运行时仍然在每个循环中工作。
for (let e = performance.now() + 2000; performance.now() < e; ) {}
这里使用setTimeout回调,即使它几乎立即进入事件队列,也要在至少两秒后才能调用:
setTimeout(function() {
console.log("timeout finished");
}, 0);
for (let e = performance.now() + 2000; performance.now() < e; ) {}
console.log("haha wait for me first");
您将经历大约两秒的暂停,然后看到:
haha wait for me first
timeout finished
在Date.now()上使用performance.now(()的好处是Date对象是
受到时钟偏斜和系统时钟调整的影响。这个时间的价值可能不总是单调增加随后的值可以减小或保持不变。*
通常,performance.now()更适合高精度地测量时间差异。
使用for循环的好处是可以在运行之前设置块的本地变量。这允许您在循环外进行加法运算,同时仍然是“单行”。这应该可以最大限度地减少这种热循环燃烧的CPU负载。
从Node.js 7.6开始,您可以将utils模块中的promisify函数与setTimeout结合起来。
const sleep = require('util').promisify(setTimeout)
一般用途
async function main() {
console.time("Slept for")
await sleep(3000)
console.timeEnd("Slept for")
}
main()
问题用法
async function asyncGenerator() {
while (goOn) {
var fileList = await listFiles(nextPageToken);
await sleep(3000)
var parents = await requestParents(fileList);
}
}