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

I'm developing a console like script for personal needs. I need to be able to pause for a extended amount of time, but, from my research, node.js has no way to stop as required. It’s getting hard to read users’ information after a period of time... I’ve seen some code out there, but I believe they have to have other code inside of them for them to work such as:

setTimeout(function() {
}, 3000);

However, I need everything after this line of code to execute after the period of time.

For example,

//start-of-code
console.log('Welcome to My Console,');
some-wait-code-here-for-ten-seconds..........
console.log('Blah blah blah blah extra-blah');
//endcode. 

I've also seen things like

yield sleep(2000);

But node.js doesnt recognize this.

How can I achieve this extended pause?

西里猿LEY2020/03/18 15:23:57

阅读完该问题的答案后,我整理了一个简单的函数,如果需要,该函数也可以执行回调:

function waitFor(ms, cb) {
  var waitTill = new Date(new Date().getTime() + ms);
  while(waitTill > new Date()){};
  if (cb) {
    cb()
  } else {
   return true
  }
}
神乐猴子2020/03/18 15:23:57

有关更多信息

yield sleep(2000); 

您应该检查Redux-Saga但这是特定于您将Redux选择为模型框架的(尽管绝对没有必要)。

猪猪小卤蛋2020/03/18 15:23:57

对于某些人来说,接受的答案无效,我找到了另一个答案,它对我也有效:如何将参数传递给setTimeout()回调?

var hello = "Hello World";
setTimeout(alert, 1000, hello); 

“ hello”是要传递的参数,您可以在超时时间之后传递所有参数。感谢@Fabio Phms的回答。

卡卡西小哥2020/03/18 15:23:57

很简单,我们将等待5秒钟,以便发生某些事件(这将由代码中其他位置的done变量设置为true表示),或者当超时到期时,我们将每100ms检查一次

    var timeout=5000; //will wait for 5 seconds or untildone
    var scope = this; //bind this to scope variable
    (function() {
        if (timeout<=0 || scope.done) //timeout expired or done
        {
            scope.callback();//some function to call after we are done
        }
        else
        {
            setTimeout(arguments.callee,100) //call itself again until done
            timeout -= 100;
        }
    })();
西门Sam2020/03/18 15:23:57

有了ES6 support Promise,我们可以在没有任何第三方帮助的情况下使用它们。

const sleep = (seconds) => {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, (seconds * 1000));
    });
};

// We are not using `reject` anywhere, but it is good to
// stick to standard signature.

然后像这样使用它:

const waitThenDo(howLong, doWhat) => {
    return sleep(howLong).then(doWhat);
};

请注意,该doWhat函数将成为中的resolve回调new Promise(...)

另请注意,这是异步睡眠。它不会阻止事件循环。如果需要阻止睡眠,请使用此库,该库可在C ++绑定的帮助下实现阻止睡眠。(尽管很少需要像异步环境一样在Node中阻塞睡眠。)

https://github.com/erikdubbelboer/node-sleep

老丝猪猪小卤蛋2020/03/18 15:23:57

由于javascript引擎(v8)根据事件队列中的事件序列运行代码,因此没有严格要求javascript在指定时间后准确触发执行。就是说,当您设置几秒钟来稍后执行代码时,触发代码纯粹是基于事件队列中的顺序。因此,触发代码执行可能要花费超过指定的时间。

因此,Node.js跟着,

process.nextTick()

以便稍后运行代码,而不是setTimeout()。例如,

process.nextTick(function(){
    console.log("This will be printed later");
});
路易猴子Pro2020/03/18 15:23:56

使用现代Java脚本实现简单优雅的睡眠功能

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

没有依赖,没有回调地狱;而已 :-)


Considering the example given in the question, this is how we would sleep between two console logs:

async function main() {
    console.log("Foo");
    await sleep(2000);
    console.log("Bar");
}

main();

The "drawback" is that your main function now has to be async as well. But, considering you are already writing modern Javascript code, you are probably (or at least should be!) using async/await all over your code, so this is really not an issue. All modern browsers today support it.

Giving a little insight into the sleep function for those that are not used to async/await and fat arrow operators, this is the verbose way of writing it:

function sleep(millis) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () { resolve(); }, millis);
    });
}

Using the fat arrow operator, though, makes it even smaller (and more elegant).

Pro神奇神奇2020/03/18 15:23:56

这是一种简单的阻止技术:

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

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

神无猪猪2020/03/18 15:23:56

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

await new Promise(resolve => setTimeout(resolve, 5000));
猴子飞云2020/03/18 15:23:56

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

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

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

For using async/await out of the box without installing and plugins, you have to use node-v7 or node-v8, using the --harmony flag.

Update June 2019: By using the latest versions of NodeJS you can use it out of the box. No need to provide command line arguments. Even Google Chrome support it today.

More info: