我如何等待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类似,但更加整洁,更容易延伸。
把你想要执行的代码放在setTimeout
callback中:
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(...)
的resolve
callback。
另外请注意,这是asynchronous睡眠。 它不会阻止事件循环。 如果您需要阻止睡眠,请使用此库,通过C ++绑定实现阻塞睡眠。 (虽然像Nodeasynchronous环境中需要阻塞睡眠是罕见的。)
欲了解更多信息
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表示不缓冲输出。