browser/node js 中的睡眠功能

sleep functionality in browser/node js

有一个数字列表 [n1,n2...] 我想打印数字然后睡眠 t1、t2 print(n2) 睡眠 t2 等

我设法“记住”了作用域,但问题是它总是只等待 1 秒。 另外,当我硬编码一个更大的值(例如 2000)时,它只会打印所有数字。

承诺:

function sleep(ms) {
    return(
        new Promise(function(resolve, reject) {
            setTimeout(function() { resolve(); }, ms);
        });
    );
}
    
for (let i = 1; i <= 100; i++) {
    sleep(i*1000).then(function() {
        console.log(i);
    });
}

与 setTimeout 相同的结果

for (let i = 1; i <= 100; i++) {
    (function(z) {
        setTimeout(
            function(){console.log(z);}, 
            z*1000
        );
    })(i);
}

for (let i = 1; i <= 100; i++) {
    (function(z){
        setTimeout(
            function(){console.log(z);}, 
            z*1000
        );
    })(i);
}

那是因为你同时启动所有的PromisesetTimeouts(),它们的时间基本会运行同时用完。

我看到两个解决你问题的方法:

  1. 您可以等待,直到 Promise 运行 结束,然后再继续您的代码
  2. 您可以将前一个setTimeout()的延迟添加到下一个
  3. 的延迟

两种解决方案 运行 都是异步的,这将为其他任务释放调用堆栈(这很重要,因为 JavaScript 运行 是单线程的)。然而,第一个解决方案更优雅,并使您的代码更具可读性。这就是为什么我只会更深入地介绍第一个。

要使 1. 正常工作,您需要将代码(或至少是异步部分)包装在异步主体中,以便能够使用 await 关键字。我们将使用 await 关键字与 PromisesetTimeout() 组合使用,就像您使用它一样,但我们将 等待 Promise待解决。

在代码中,这可能是这样的:
注意:立即调用的包装函数表达式称为 IIFE

function sleep(ms) {
  return new Promise(res => setTimeout(res, ms));
}

(async function() {
  for (let i = 1; i <= 100; i++) {
    console.log(i);
    await sleep(i*1000);
  }
})();