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

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


当前回答

为了在javascript中“等待”,使用承诺是一种方法,正如上面的答案所示。

那么如何使用它呢?

下面是一个简单的例子,一个5秒的子进程以非阻塞的方式为一个4秒的主进程排队参数。

const wait = (seconds) => 
    new Promise(resolve => 
        setTimeout(() => 
            resolve(true), seconds * 1000))

const process = async (items, prepTask, mainTask) => {
    const queue = [];
    let done = false;

    items.forEach((item, i) => {
        prepTask(item).then(() => {
            queue.push(item);
            if (i == items.length -1) {
                done = true;
            }
        })
    })

    while (!done || queue.length) {
        if (queue.length) {
            const workload = queue.shift();
            await mainTask(workload)
        } else {
            console.log('waiting for subtask to queue')
            await wait(1);
        }
    }
}

// Usage Example

const ids = [1,2,3,4,5,6,7,8,9,10];

const prepTask = async (id) => {
    await wait(id * 5)
    return id * 5;
}

const mainTask = async (workload) => {
    console.log('excuting workload: ', workload);
    const result = await wait(4);
    return { workload, result }
}

process(ids, prepTask, mainTask)
    .then(() => console.log('done'))

其他回答

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

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

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

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

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

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

如果脚本中没有其他事情发生(比如回调),那么它就是阻塞的。但由于这是一个控制台脚本,也许它就是您所需要的!

如果你只是为了测试而挂起当前线程执行,试试这个:

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

这是一个moment.js风格的模块,基于@atlex2建议的脏块方法。仅用于测试。

const moment = require('moment');

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

module.exports = sleep;

Node 7.6.0或更高版本

节点支持本地等待:

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

然后如果你可以使用异步函数:

await sleep(10000); // sleep for 10 seconds

or:

sleep(10000).then(() => {
  // This will execute 10 seconds from now
});

在较旧的Node版本上(原始答案)

我想要一个在Windows和Linux中工作的异步睡眠,而不会占用CPU很长的while循环。我尝试了睡眠包,但它无法安装在我的Windows盒子上。我最终使用:

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

要安装它,输入:

npm install system-sleep

在你的代码中,

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

效果非常好。