我如何在 Node.js (JavaScript) 中等待?我需要暂停一段时间

IT技术 javascript node.js async-await yield
2021-02-08 11:52:01

我正在为个人需要开发一个控制台脚本。我需要能够暂停很长时间,但是,根据我的研究,Node.js 无法按要求停止。一段时间后,阅读用户信息变得越来越困难......我已经看到了一些代码,但我相信他们必须在其中包含其他代码才能工作,例如:

    setTimeout(function() {
    }, 3000);

但是,我需要在这行代码之后的所有内容在一段时间后执行。

例如,

    // start of code
    console.log('Welcome to my console,');

    some-wait-code-here-for-ten-seconds...

    console.log('Blah blah blah blah extra-blah');
    // end of code

我也看过类似的东西

    yield sleep(2000);

但是 Node.js 不承认这一点。

我怎样才能实现这种延长的暂停?

6个回答

2021 年 1 月更新:您甚至可以使用--experimental-repl-await标志在 Node REPL 交互中执行此操作

$ node --experimental-repl-await
> const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
> await delay(1000) /// waiting 1 second.

一个老问题的新答案。今天(20171月 20196 月)要容易得多。您可以使用async/await语法例如:

async function init() {
  console.log(1);
  await sleep(1000);
  console.log(2);
}

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

async/await在不安装和插件的情况下开箱即用,您必须使用 node-v7 或 node-v8,并使用该--harmony标志。

2019 年 6 月更新:通过使用最新版本的 NodeJS,您可以开箱即用。无需提供命令行参数。今天甚至谷歌浏览器都支持它。

2020 年 5 月更新: 很快您将能够在await异步函数之外使用语法。在这个例子中的顶层

await sleep(1000)
function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

该提案处于第 3 阶段你今天可以通过使用 webpack 5 (alpha) 来使用它,

更多信息:

这真的应该是答案, sleep node.js 包可能很麻烦。
2021-03-23 11:52:01
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 对于像我这样的单线怪胎:)
2021-03-25 11:52:01
我想你忘记了await前面关键字sleep(1000)
2021-04-02 11:52:01
这救了我今天的培根(特别是promisify@BrianHVB 发布食谱)。
2021-04-06 11:52:01
let sleep = require('util').promisify(setTimeout); 适用于 Node 7.6+ 并提高可读性
2021-04-11 11:52:01

没有任何依赖的最短解决方案:

await new Promise(resolve => setTimeout(resolve, 5000));
这个不错。不过,您必须使用 NodeJS 7.6.0 或更高版本。它不适用于旧版本。
2021-03-16 11:52:01
为避免 eslint 投诉,请调用它resolve而不是done. IEawait new Promise(resolve => setTimeout(resolve, 5000))
2021-04-02 11:52:01
“复杂的高度是简单。” ——克莱尔·布斯·卢斯。这是迄今为止最好的答案,IMO。
2021-04-03 11:52:01
这显然比其他答案更新得多,但它是 2018 年最优雅的方法,可以在 1 行中完成工作,而不会对代码产生任何其他影响。
2021-04-05 11:52:01
let sleep = require('util').promisify(setTimeout); 是三个字符长但可重复使用和更易读的imo
2021-04-05 11:52:01

最好的方法是将您的代码分解为多个函数,如下所示:

function function1() {
    // stuff you want to happen right away
    console.log('Welcome to My Console,');
}

function function2() {
    // all the stuff you want to happen after that pause
    console.log('Blah blah blah blah extra-blah');
}

// call the first chunk of code right away
function1();

// call the rest of the code and have it execute after 3 seconds
setTimeout(function2, 3000);

它类似于JohnnyHK的解决方案,但更简洁,更易于扩展。

这是异步的,这意味着如果 function1 在 3 秒之前终止,它们将开始相互重叠。然后你甚至无法返回,它几乎永远无法使用。到目前为止我发现的唯一方法是使用debugger;
2021-03-31 11:52:01
当函数的开始不是只有一个函数,而是离需要去异步化的代码有 10 个文件时,你会怎么做?
2021-04-03 11:52:01
@LucasSeveryn 那么你做错了什么。这是一个核心设计模式。
2021-04-04 11:52:01
@CyrilDuchon-Doris 什么?
2021-04-08 11:52:01
使用@machineghost 的答案来获得一个优雅的基于Promise的解决方案,该解决方案不需要自定义代码并支持等待/异步
2021-04-10 11:52:01

这是一个简单的阻塞技术:

var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}

只要脚本中不会发生任何其他事情(例如回调),它就会阻塞但由于这是一个控制台脚本,也许它正是您所需要的!

可怕与否,它做一个简单的wait,它阻止并且它用于某些测试目的。正是我正在寻找的。
2021-03-14 11:52:01
@Ali 这似乎是目标。
2021-03-20 11:52:01
这是问题的唯一正确答案。OP 特别要求调用等待函数,从函数返回,然后继续。(没有回调,没有异步任何东西,没有重写你的整个调用堆栈来处理Promise。)唯一可以完全满足 OP 要求的其他解决方案是调用外部程序,例如SLEEP.EXE在 Windows 上。
2021-03-20 11:52:01
这是一个spin-wait.
2021-03-22 11:52:01
完美地回答了没有 3rd 方库的问题,而且很简单。然而人们说“可怕”......这非常适合模拟沉重的 CPU 负载等。顺便说一句,与phpied.com/sleep-in-javascript非常相似
2021-03-24 11:52:01

将您要在延迟后执行的代码放入setTimeout回调中:

console.log('Welcome to My Console,');
setTimeout(function() {
    console.log('Blah blah blah blah extra-blah');
}, 3000);
@ChristopherKemp:原来 Node.js 有一个解决方案,叫做node-fibers. 看看这个。
2021-03-14 11:52:01
@ElliotBonneville 这只是说明这个概念的一个例子。显然,您可以(应该)将代码分解为函数调用,而不是像其他任何地方一样使用内联代码。
2021-03-20 11:52:01
这是非常混乱并且通常是不好的做法,特别是如果 OP 希望程序的其余部分在该延迟之后运行。看我的回答。
2021-03-28 11:52:01
这是一个很好的解决方案,特别是如果您不想执行任何代码,而只想在循环中模拟“睡眠”方法。这个例子没有任何问题。
2021-04-05 11:52:01
这非常适合延迟来自客户端的请求,我使用这种方法在客户端测试我的加载微调器
2021-04-05 11:52:01