我正在为个人需求开发一个控制台脚本。我需要能够暂停更长的时间,但是,根据我的研究,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不能识别这个。

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


当前回答

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

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

但在我看来,真正理想的答案是使用Node的util库和它的promisify函数,它正是为这类事情而设计的(为先前存在的基于承诺的东西制作基于承诺的版本):

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

在任何一种情况下,你都可以使用await调用你的睡眠函数来暂停:

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

编辑:正如评论中所指出的,你甚至可以把它减少到一行:

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

或者,如果你甚至不想费心创建一个睡眠函数:

await require('util').promisify(setTimeout)(1000);

其他回答

在Linux/nodejs上,这对我来说是有效的:

const spawnSync = require('child_process').spawnSync; var sleep = spawnSync('sleep', [1.5]);

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

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

由于javascript引擎(v8)是基于事件队列中的事件顺序运行代码的,因此没有严格的规定javascript在指定的时间后准确地触发执行。也就是说,当您设置几秒后执行代码时,触发代码完全基于事件队列中的顺序。因此,触发代码执行的时间可能会超过指定的时间。

node。js遵循,

process.nextTick()

来代替setTimeout()运行代码。例如,

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

其他的答案都很好,但我想我要采取不同的策略。

如果你真正想要的只是在linux中减慢一个特定的文件:

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

节点myprog slowfile

这将每5行休眠1秒。节点程序将和写入程序一样慢。如果它在做其他事情,它们将继续以正常速度运行。

mkfifo创建了一个先进先出管道。这就是它的作用。 perl行可以像你想要的那样快。$|=1表示不缓冲输出。

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

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

但在我看来,真正理想的答案是使用Node的util库和它的promisify函数,它正是为这类事情而设计的(为先前存在的基于承诺的东西制作基于承诺的版本):

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

在任何一种情况下,你都可以使用await调用你的睡眠函数来暂停:

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

编辑:正如评论中所指出的,你甚至可以把它减少到一行:

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

或者,如果你甚至不想费心创建一个睡眠函数:

await require('util').promisify(setTimeout)(1000);

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

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

没有依赖,没有回调;就是这样:-)


考虑到问题中给出的例子,这是我们在两个控制台日志之间睡眠的方式:

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

main();

“缺点”是你的主函数现在也必须是异步的。但是,考虑到您已经在编写现代Javascript代码,您可能(或者至少应该!)在所有代码中使用async/await,所以这真的不是一个问题。现在所有的浏览器都支持它。

对于那些不习惯async/await和胖箭头操作符的人,稍微深入了解一下sleep函数,下面是详细的书写方式:

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

但是,使用胖箭头操作符会使它更小(也更优雅)。