Как я могу ждать в Node.js(Javascript), мне нужно приостановить на некоторое время

Я разрабатываю консоль вроде script для личных нужд... Мне нужно сделать паузу в течение продолжительного времени, но поскольку 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');
//endcode. 

Я также видел такие вещи, как

yield sleep(2000);

Но node.js не распознает это....

Если кто-то хочет помочь, он очень ценится.

4b9b3361

Лучший способ сделать это - разбить код на несколько функций, например:

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, но намного опережает и упрощается.

95
ответ дан 10 янв. '13 в 4:46
источник

Поместите код, который вы хотите выполнить после задержки в обратном вызове setTimeout:

console.log('Welcome to My Console,');
setTimeout(function() {
    console.log('Blah blah blah blah extra-blah');
}, 3000);
105
ответ дан 10 янв. '13 в 4:44
источник

Это простой метод блокировки:

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

Он блокируется, поскольку в вашем script (например, обратном вызове) ничего не произойдет. Но поскольку это консоль script, возможно, это то, что вам нужно!

77
ответ дан 01 июня '16 в 20:51
источник

Новый ответ на старый вопрос. Сегодня (январь 2017) это намного проще. Вы можете использовать новый синтаксис 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.

Дополнительная информация:

54
ответ дан 31 янв. '17 в 15:05
источник

Этот вопрос довольно старый, но в последнее время V8 добавил генераторы, которые могут выполнить то, что запросил OP. Генераторы обычно проще всего использовать для асинхронных взаимодействий с помощью библиотеки, такой как suspend или gen-run.

Вот пример использования suspend:

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

Связанное чтение (посредством бесстыдной саморекламы): Какая большая сделка с генераторами?.

33
ответ дан 21 авг. '13 в 17:11
источник

Простая и элегантная функция сна с использованием современного Javascript

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

Нет зависимостей, нет аддонов обратного вызова; что он: -)


Учитывая пример, приведенный в вопросе, мы будем ждать между двумя консольными журналами:

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

main();

"Недостаток" заключается в том, что ваша основная функция должна быть async. Но, учитывая, что вы уже пишете современный код Javascript, вы должны использовать async/await по всему вашему коду, так что это действительно не проблема. Сегодня все современные браузеры уже поддерживают его. Даже Edge!

Предоставляя небольшое представление о функции sleep для тех, которые не используются для async/await, вы также можете записать это следующим образом:

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

Использование оператора толстой стрелки, тем не менее, делает его еще меньшим (и более элегантным).

21
ответ дан 13 окт. '17 в 3:14
источник

Недавно я создал более простую абстракцию под названием wait.for для вызова асинхронных функций в режиме синхронизации (на основе node -fibers). Существует также версия, основанная на будущих генераторах ES6.

https://github.com/luciotato/waitfor

Используя wait.for, вы можете вызвать любую стандартную функцию async nodejs, как если бы это была функция синхронизации, без блокировки цикла событий node.

Вы можете кодировать последовательно, когда вам это нужно, а именно (я предполагаю), чтобы упростить ваши скрипты для личного использования.

используя 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. 

Также любая функция асинхронизации может быть вызвана в режиме синхронизации. Проверьте примеры.

13
ответ дан 06 сент. '13 в 16:58
источник

В Linux/nodejs это работает для меня:

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

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

Он блокируется, но он не занят циклом ожидания.

Время, указанное вами, указано в секундах, но может быть дробным. Я не знаю, имеет ли другая ОС аналогичную команду.

13
ответ дан 18 нояб. '16 в 21:50
источник

Мне нужен асинхронный сон, который работал в Windows и Linux, не забивая мой процессор длинным циклом. Я попробовал пакет сна, но он не будет установлен на моем ящике Windows. Я закончил использование:

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

Чтобы установить его, введите:

npm install system-sleep

В вашем коде

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

Работает как шарм.

11
ответ дан 13 янв. '17 в 21:56
источник

Так как javascript engine (v8) запускает код, основанный на последовательности событий в очереди событий, нет строгого, чтобы javascript точно запускал выполнение по истечении указанного времени. То есть, когда вы установите несколько секунд для выполнения кода позже, запуск кода является чисто основанием для последовательности в очереди событий. Поэтому запуск выполнения кода может занять более определенного времени.

Итак, Node.js следует,

process.nextTick()

чтобы позже запустить код вместо setTimeout(). Например,

process.nextTick(function(){
    console.log("This will be printed later");
});
6
ответ дан 10 янв. '13 в 14:22
источник

Если вы хотите "code golf", вы можете сделать более короткую версию некоторых других ответов здесь:

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

Но на самом деле идеальным ответом, по моему мнению, является использование библиотеки Node util и ее функции promisify, которая предназначена именно для такого рода вещей (создание версий, основанных на обещаниях ранее существующих, основанные на материалах):

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

В любом случае вы можете просто сделать паузу, используя await для вызова функции sleep:

await sleep(1000); // sleep for 1s/1000ms
4
ответ дан 24 окт. '17 в 3:38
источник

Самое короткое решение без каких-либо зависимостей:

await new Promise(done => setTimeout(done, 5000));
4
ответ дан 06 марта '18 в 23:47
источник

Если ES6 поддерживает Promise s, мы можем использовать их без помощи сторонних разработчиков.

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(...).

Также обратите внимание, что это ASYNCHRONOUS sleep. Он не блокирует цикл события. Если вам нужна блокировка сна, используйте эту библиотеку, которая реализует блокировку сна с помощью привязок С++. (Хотя необходимость блокировки сна в Node, например, в async-средах, редка.)

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

2
ответ дан 18 мая '17 в 3:34
источник
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');
});

Этот код, приведенный выше, является побочным эффектом решения азартной проблемы азартного обратного вызова Javascript. Это также причина, по которой я считаю, что Javascript - полезный язык в бэкэнд. На самом деле это самое захватывающее усовершенствование, появившееся на современном Javascript, на мой взгляд. Чтобы полностью понять, как это работает, как работает генератор, необходимо полностью понять. Ключевое слово function, за которым следует *, называется функцией генератора в современном Javascript. В пакете npm co предусмотрена функция runner для запуска генератора.

По существу функция генератора обеспечивала возможность приостановки выполнения функции с ключевым словом yield, в то же время yield в функции генератора позволяла обмениваться информацией между внутри генератора и вызывающей. Это обеспечило механизм для того, чтобы вызывающий абонент извлекал данные из promise из асинхронного вызова и передавал разрешенные данные обратно генератору. Фактически, он делает синхронный асинхронный вызов.

1
ответ дан 08 марта '17 в 12:58
источник

Это ароматизированный модуль 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;
0
ответ дан 08 нояб. '17 в 17:11
источник

Посмотрите на 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);
  }
}

Может быть, не самая лучшая практика, но делает работу для меня

0
ответ дан 27 авг. '17 в 1:01
источник

Для некоторых людей принятый ответ не работает, я нашел этот другой ответ, и он работает для меня: Как передать параметр в callbackTimeout()?

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

'hello' - передаваемый параметр, вы можете передать все параметры после таймаута. Спасибо @Fabio Phms за ответ.

0
ответ дан 13 апр. '17 в 21:49
источник

просто мы будем ждать 5 секунд для того, чтобы какое-то событие произошло (это будет указано, если указанная переменная установлена ​​в true в другом месте), или когда истечет время ожидания, мы проверим каждые 100 мс

    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;
        }
    })();
0
ответ дан 22 марта '17 в 17:54
источник

Если вам просто нужно приостановить тестирование, вы выполняете текущее выполнение потока:

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
0
ответ дан 29 нояб. '16 в 12:19
источник

Для получения дополнительной информации о

yield sleep(2000); 

вы должны проверить Redux-Saga. Но он специфичен для вашего выбора Redux как вашей модели (хотя и не обязательно).

-1
ответ дан 09 сент. '16 в 12:24
источник

Другие ответы велики, но я думал, что возьму другой такт.

Если все, что вы действительно ищете, это замедлить определенный файл в linux:

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

node myprog slowfile

Это будет спать 1 сек каждые пять строк. Программа node будет работать медленнее, чем писатель. Если он делает другие вещи, они будут продолжать с нормальной скоростью.

mkfifo создает первую очередь в первом канале. Это то, что делает эту работу. Линия perl будет писать так быстро, как вы хотите. Утверждение $| = 1 не буферизует вывод.

-1
ответ дан 14 марта '17 в 0:11
источник

Я собрал вместе, прочитав ответы в этом вопросе, простую функцию, которая также может выполнять обратный вызов, если вам это нужно:

function waitFor(ms, cb) {
  var waitTill = new Date(new Date().getTime() + ms);
  while(waitTill > new Date()){};
  if (cb) {
    cb()
  } else {
   return true
  }
}
-2
ответ дан 06 нояб. '16 в 11:08
источник