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

我正在为个人需要开发一个类似脚本的控制台…我需要能够暂停一段时间,但是由于我的研究中的node.js无法根据需要停止….在一段时间后读取用户信息… iv看到了一些代码,但我相信他们必须有其他代码在他们的工作,如:

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'); //endcode. 

我也看过像

 yield sleep(2000); 

但是node.js不能识别这个….

如果有人愿意帮助,那么非常感激。

最好的办法是将你的代码分解成多个函数,如下所示:

 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的解决scheme类似,但更加整洁,更容易延伸。

把你想要执行的代码放在setTimeoutcallback中:

 console.log('Welcome to My Console,'); setTimeout(function() { console.log('Blah blah blah blah extra-blah'); }, 3000); 

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

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

只要你的脚本中没有其他东西会发生(比如callback),就会阻塞它。 但既然这是一个控制台脚本,也许这是你需要的!

你可以使用这个www.npmjs.com/package/sleep

 var sleep = require('sleep'); sleep.sleep(10); // sleep for ten seconds 

这个问题是相当古老的,但最近V8增加了发电机,可以完成OP所要求的。 生成器通常是最容易使用的asynchronous交互与图书馆的协助,如暂停或发电。

这是一个使用暂停的例子:

 suspend(function* () { console.log('Welcome to My Console,'); yield setTimeout(suspend.resume(), 10000); // 10 seconds pass.. console.log('Blah blah blah blah extra-blah'); })(); 

相关阅读(通过无耻的自我推销方式): 什么是发电机的大事? 。

一个老问题的新答案。 今天(2017年1月)更容易了。 您可以使用新的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标志。

更多信息:

  • Nodejs中的和谐标志: https ://nodejs.org/en/docs/es6/
  • 所有NodeJS版本供下载: https : //nodejs.org/en/download/releases/

我最近创build了一个叫wait.for的简单抽象,以同步模式调用asynchronous函数(基于节点光纤)。 还有一个基于即将到来的ES6发电机的版本。

https://github.com/luciotato/waitfor

使用wait.for ,你可以调用任何标准的nodejsasynchronous函数,就好像它是一个同步函数,而不会阻塞节点的事件循环。

你可以在需要的时候按顺序编码,也就是(我猜)完美可以简化个人使用的脚本。

使用wait.for你的代码将是:

 require('waitfor') ..in a fiber.. //start-of-code console.log('Welcome to My Console,'); wait.miliseconds(10*1000); //defined in waitfor/paralell-tests.js - DOES NOT BLOCK console.log('Blah blah blah blah extra-blah'); //endcode. 

同步模式下也可以调用任何asynchronous函数。 检查例子。

在Linux / nodejs上,这适用于我:

const spawnSync = require('child_process')。spawnSync;

var sleep = spawnSync('sleep',[1.5]);

它阻塞,但它不是一个繁忙的等待循环。

您指定的时间以秒为单位,但可以是分数。 我不知道其他操作系统是否有类似的命令。

我想要一个在Windows和Linux中工作的asynchronous睡眠,而不用占用很长一段时间的CPU。 我尝试了睡眠包,但它不会安装在我的Windows机器上。 我结束了使用:

https://www.npmjs.com/package/system-sleep

要安装它,请键入:

 npm install system-sleep 

在你的代码中,

 var sleep = require('system-sleep'); sleep(10*1000); // sleep for 10 seconds 

奇迹般有效。

因为,JavaScript引擎(v8)根据事件队列中事件的顺序来运行代码,没有严格的规定,在指定的时间之后,javascript会严格触发执行。 也就是说,当您稍后设置一些秒来执行代码时,触发代码纯粹是基于事件队列中的序列。 所以触发代码的执行可能需要超过指定的时间。

所以Node.js接下来,

 process.nextTick() 

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

 process.nextTick(function(){ console.log("This will be printed later"); }); 

使用现代Javascript简单而优雅的睡眠function

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

没有依赖关系,没有callback的地狱; 而已 :-)


考虑到问题中给出的例子,我们将如何在两个控制台日志之间等待:

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

“缺点”是你的主要function也必须是async 。 但是,考虑到你已经写了现代的Javascript代码,你应该使用async / await你的代码,所以这真的不是一个问题。 今天所有的现代浏览器已经支持它。 即使是边缘!

对那些不习惯async/await人的sleep函数有一点点的了解,你也可以这样写:

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

然而,使用胖箭头操作符使其更小(更优雅)。

 let co = require('co'); const sleep = ms => new Promise(res => setTimeout(res, ms)); co(function*() { console.log('Welcome to My Console,'); yield sleep(3000); console.log('Blah blah blah blah extra-blah'); }); 

以上代码是解决Javascriptasynchronouscallback问题的副作用。 这也是我认为使Javascript成为后台有用语言的原因。 其实这是我认为现代Javascript引入的最激动人心的改进。 为了充分理解它是如何工作的,发电机的工作方式需要被充分理解。 在现代Javascript中, function关键字后跟一个*被称为生成器函数。 npm软件包提供了一个runner函数来运行一个generator。

基本上,生成器函数提供了一种用yield关键字来暂停函数执行的方法,同时,生成器函数中的yield可以在生成器和调用者之间交换信息。 这为调用者提供了一种机制,可以从asynchronous调用的promise提取数据,并将parsing的数据传回给生成器。 有效地,它使asynchronous调用同步。

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

 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函数将成为new Promise(...)resolvecallback。

另外请注意,这是asynchronous睡眠。 它不会阻止事件循环。 如果您需要阻止睡眠,请使用此库,通过C ++绑定实现阻塞睡眠。 (虽然像Nodeasynchronous环境中需要阻塞睡眠是罕见的。)

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

欲了解更多信息

 yield sleep(2000); 

你应该检查Redux-Saga 。 但是,您selectRedux作为您的模型框架是特定的(尽pipe严格没有必要)。

如果你只是暂停testing目的,你当前的线程执行试试这个:

 function longExecFunc(callback, count) { for (var j = 0; j < count; j++) { for (var i = 1; i < (1 << 30); i++) { var q = Math.sqrt(1 << 30); } } callback(); } longExecFunc(() => { console.log('done!')}, 5); //5, 6 ... whatever. Higher -- longer 

简单的说,我们将等待5秒钟发生一些事件(这可以通过在代码中的其他地方将donevariables设置为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; } })(); 

对于一些人来说,接受的答案是行不通的,我发现了这个答案,它是为我工作:我怎样才能传递一个参数setTimeout()callback?

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

'hello'是被传递的参数,你可以在超时时间之后传递所有的参数。 感谢@Fabio Phms的答案。

看看readline-sync( https://www.npmjs.com/package/readline-sync

使用npm install readline-sync

 var readlineSync = require('readline-sync'); while(true) { var input = readlineSync.question("What is your input?"); if(input === 'exit') { process.exit(); } else { console.log("Your input was " + input); } } 

也许不是最好的做法,但为我做的工作

如果你想“编码高尔夫球”,你可以在这里做一些其他答案的简短版本:

 const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); 

但在我看来,真正理想的答案是使用Node的util函数库及其promisify函数,这正是为这种事情devise的(使基于承诺的版本以前存在的基于非promise的东西):

 const util = require('util'); const sleep = util.promisify(setTimeout); 

在这两种情况下,您都可以简单地通过使用await来调用您的sleep函数来暂停:

 await sleep(1000); // sleep for 1s/1000ms 

这是一个基于@ atlex2build议的肮脏阻塞方法的moment.js风格模块。 只用于testing

 const moment = require('moment'); let sleep = (secondsToSleep = 1) => { let sleepUntill = moment().add(secondsToSleep, 'seconds'); while(moment().isBefore(sleepUntill)) { /* block the process */ } } module.exports = sleep; 

在阅读了这个问题的答案后,我把它放在一起,一个简单的函数也可以做callback,如果你需要的话:

 function waitFor(ms, cb) { var waitTill = new Date(new Date().getTime() + ms); while(waitTill > new Date()){}; if (cb) { cb() } else { return true } } 

其他答案很好,但我想我会采取不同的机智。

如果你真的想要的是在Linux中放慢特定的文件:

  rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile & 

节点myprog慢文件

这将每5行睡1秒。 节点程序将会像作者一样慢。 如果正在做其他事情,他们会以正常的速度继续。

mkfifo创build一个先进先出的pipe道。 这是什么使这项工作。 perl行将尽可能快地写入。 $ | = 1表示不缓冲输出。