Как Я Могу Ждать В Узле.js (Javascript), l нужно сделать паузу на некоторое время
Я разрабатываю консоль, как скрипт для личных нужд...
Мне нужно быть в состоянии сделать паузу на длительное время, но как узел.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);
но узел.js не признает этого....
Если кто-то готов помочь, это очень ценится.
23 ответов:
лучший способ сделать это-разбить ваш код на несколько функций, например:
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решение, но гораздо аккуратнее и легче расширить.
вставляете код, который вы хотите выполнить после задержки в элементе
setTimeoutобратного вызова:console.log('Welcome to My Console,'); setTimeout(function() { console.log('Blah blah blah blah extra-blah'); }, 3000);
новый ответ на старый вопрос. Сегодня (январь 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флаг.Подробнее:
- флаг гармонии в Nodejs:https://nodejs.org/en/docs/es6/
- все версии NodeJS для загрузки: https://nodejs.org/en/download/releases/
Это простой метод блокирования:
var waitTill = new Date(new Date().getTime() + seconds * 1000); while(waitTill > new Date()){}Это блокировка поскольку ничего больше не произойдет в вашем скрипте (например, обратные вызовы). Но так как это консольный скрипт, может быть, это то, что вам нужно!
вы можете использовать это www.npmjs.com/package/sleep
var sleep = require('sleep'); sleep.sleep(10); // sleep for ten seconds
этот вопрос довольно старый, но недавно V8 добавил генераторы, которые могут выполнить то, что запросил OP. Генераторы, как правило, проще всего использовать для асинхронных взаимодействий с помощью библиотеки, такой как приостановить или 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'); })();связанное чтение (путем бесстыдного саморекламы):в чем проблема с генераторами?.
простая и элегантная функция сна с использованием современного 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по всему коду, так что это действительно не проблема. Все современные браузеры сегодня поддержка его.давая небольшое представление о
sleepфункция для тех, которые не используются дляasync/await, вы также можете написать это так:async function sleep(millis) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, millis); }); }использование оператора fat arrow, однако, делает его еще меньше (и более элегантным).
самое короткое решение без каких-либо зависимостей:
await new Promise(done => setTimeout(done, 5000));
недавно я создал более простую абстракцию под названием подождать.ибо для вызова асинхронных функций в режиме синхронизации (на основе узла-волокон). Существует также версия, основанная на предстоящих генераторах ES6.
https://github.com/luciotato/waitfor
С помощью подождать.ибо, вы можете вызвать любую стандартную асинхронную функцию nodejs, как если бы это была функция синхронизации, без блокировки цикла событий узла.
вы можете кодировать последовательно, когда вам нужно это, что, (я предполагаю) идеально подходит для упрощения ваших сценариев для личного использования.
С помощью подождать.ибо ваш код будет:
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.также любая асинхронная функция может быть вызвана в синхронизация режим. Проверьте примеры.
на Linux / nodejs это работает для меня:
const spawnSync = require ('child_process').spawnSync;
var sleep = spawnSync ('sleep', [1.5]);
он блокирует, но это не занятый цикл ожидания.
время, указанное в секундах, но может быть частью. Я не знаю, есть ли у других ОС аналогичная команда.
Я хотел асинхронный сон, который работал в 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работает как шарм.
если вы хотите "код гольф" вы можете сделать более короткую версию некоторых других ответов здесь:
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));но на самом деле идеальным ответом на мой взгляд является использование узла
utilиpromisifyфункция, которая предназначена именно для такого рода вещей (создание версий на основе обещаний ранее существующих вещей, не основанных на обещаниях):const util = require('util'); const sleep = util.promisify(setTimeout);в любом случае вы можете сделать паузу, просто используя
awaitдля вызоваsleepфункция:await sleep(1000); // sleep for 1s/1000ms
поскольку JavaScript engine (v8) запускает код на основе последовательности событий в очереди событий, нет строгого требования, чтобы javascript точно запускал выполнение после указанного времени. То есть, когда вы устанавливаете несколько секунд для выполнения кода позже, запускающий код является чисто базовым по последовательности в очереди событий. Таким образом, запуск выполнения кода может занять больше указанного времени.
Итак Узла.js следует,
process.nextTick()чтобы запустить код позже вместо setTimeout (). Для например,
process.nextTick(function(){ console.log("This will be printed later"); });
С поддержкой ES6
Promises, мы можем использовать их без какой-либо сторонней помощи.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); };отметим, что становится
resolveобратный вызов в пределахnew Promise(...).также обратите внимание, что это асинхронный сон. Он не блокирует цикл событий. Если вам нужна блокировка сна, используйте эту библиотеку, которая реализует блокировку сна с помощью привязок C++. (Хотя необходимость блокировки сна в узле нравится асинхронные среды встречаются редко.)
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 hell. Это также причина, по которой я думаю, что делает Javascript полезным языком в бэкэнде. На самом деле это самое захватывающее улучшение, введенное в современный Javascript, на мой взгляд. Чтобы полностью понять, как это работает, как работает генератор должен быть полностью понят. Элемент
functionключевое слово, за которым следует*называется функцией генератора в современном Javascript. Пакет npmcoпри условии, что функция бегуна для запуска генератора.по существу функция генератора обеспечила способ приостановить выполнение функции с
yieldключевое слово, в то же время,yieldв генераторе функция сделала возможным обмен информацией между внутри генератора и вызывающего абонента. Это обеспечило механизм для вызывающего абонента для извлечения данных изpromiseот асинхронного вызова и передать разрешенные данные обратно в генератор. Эффектно, оно делает асинхронный вызов синхронный.
Если вам просто нужно приостановить для тестирования цели вы текущее выполнение потока попробуйте это:
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 секунд, чтобы произошло какое-то событие (которое будет указано переменной done, установленной в 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; } })();
для некоторых людей принятый ответ не работает, я нашел этот другой ответ, и он работает для меня:Как я могу передать параметр в обратный вызов setTimeout ()?
var hello = "Hello World"; setTimeout(alert, 1000, hello);'hello' - это передаваемый параметр, вы можете передать все параметры после времени ожидания. Спасибо @Fabio Phms за ответ.
взгляните на readline-sync (https://www.npmjs.com/package/readline-sync)
установить с
npm install readline-syncvar 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); } }может быть, не лучшая практика, но делает работу для меня
этот момент.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;
другие ответы отличные, но я решил взять другой подход.
Если все, что вы действительно ищете, это замедлить определенный файл в linux:
rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile &узел myprog slowfile
Это будет спать 1 сек каждые пять строк. Программа узла будет идти так же медленно, как и писатель. Если он делает другие вещи, они будут на нормальной скорости.
mkfifo создает первый вход-первый выход трубы. Это то, что делает эту работу. Строки в Perl буду писать так быстро, как вы хотите. $ / =1 говорит, что не буферизует выход.
подробнее о
yield sleep(2000);вы должны проверить Redux-Saga. Но это зависит от вашего выбора Redux в качестве модели фреймворка (хотя строго не обязательно).
Я собрал, прочитав ответы на этот вопрос, простую функцию, которая также может выполнять обратный вызов, если вам это нужно:
function waitFor(ms, cb) { var waitTill = new Date(new Date().getTime() + ms); while(waitTill > new Date()){}; if (cb) { cb() } else { return true } }
Comments