Я разрабатываю консольный скрипт для личных нужд. Я должен быть в состоянии сделать паузу в течение длительного периода времени, но, согласно моим исследованиям, 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
node.js
yield
Кристофер Аллен
источник
источник
require("child_process").execSync('php -r "sleep($argv[1]);" ' + seconds);
Ответы:
Лучший способ сделать это - разбить ваш код на несколько функций, например:
Это похоже на решение JohnnyHK , но гораздо удобнее и проще в расширении.
источник
debugger;
Новый ответ на старый вопрос. Сегодня (
январь 2017,июнь 2019) это намного проще. Вы можете использовать новыйasync/await
синтаксис . Например:Для использованияasync/await
из коробки без установки и плагинов, вы должны использовать node-v7 или node-v8, используя--harmony
флаг.Обновление от июня 2019 года. Используя последние версии NodeJS, вы можете использовать его «из коробки». Не нужно указывать аргументы командной строки. Даже Google Chrome поддерживает это сегодня.
Обновление май 2020: скоро вы сможете использовать
await
синтаксис вне асинхронной функции. На верхнем уровне, как в этом примереПредложение находится на стадии 3 . Вы можете использовать его сегодня с помощью веб-пакета 5 (альфа),
Больше информации:
источник
await
ключевое слово передsleep(1000)
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Для странных фанатов, как я :)let sleep = require('util').promisify(setTimeout);
работает на узле 7.6+ и улучшает читаемостьСамое короткое решение без каких-либо зависимостей:
источник
let sleep = require('util').promisify(setTimeout);
на три символа длиннее, но многоразового использования и более читабельного imoresolve
вместоdone
. Т.е.await new Promise(resolve => setTimeout(resolve, 5000))
Поместите код, который вы хотите выполнить после задержки в
setTimeout
обратном вызове:источник
node-fibers
. Проверьте это.Это простая техника блокировки:
Он блокируется, поскольку в вашем скрипте больше ничего не произойдет (например, обратные вызовы). Но так как это консольный скрипт, возможно, это то, что вам нужно!
источник
wait
, это блокирует, и это работает для некоторой цели тестирования. Именно то, что я искал.spin-wait
.На узле 7.6.0 или выше
Node поддерживает ожидание изначально:
тогда, если вы можете использовать асинхронные функции:
или:
На старых версиях Node (оригинальный ответ)
Я хотел асинхронный сон, который работал бы в Windows и Linux, не перегружая мой процессор длительным циклом. Я попробовал спящий пакет, но он не установился на мой Windows-бокс. Я закончил тем, что использовал:
https://www.npmjs.com/package/system-sleep
Чтобы установить его, введите:
В вашем коде
Работает как шарм.
источник
Простая и элегантная функция сна с использованием современного Javascript
Нет зависимостей, нет ада обратного вызова; это оно :-)
Учитывая пример, приведенный в вопросе, вот как мы будем спать между двумя журналами консоли:
Недостатком является то, что ваша основная функция теперь должна быть
async
такой же. Но, учитывая, что вы уже пишете современный код Javascript, вы, вероятно, (или, по крайней мере, должны!) Использоватьasync
/await
весь код, так что это действительно не проблема. Все современные браузеры сегодня поддерживают это.Дадим небольшое представление о
sleep
функции для тех, кто не привык кasync/await
жирным стрелкам и операторам, это подробный способ ее написания:Однако использование оператора жирной стрелки делает его еще меньше (и более элегантным).
источник
async
и оставляя все то же самое. Это, вероятно, яснее,async
хотя.async
. Отредактировал мой ответ с вашим предложением. Я не думаю, что это делает код более понятным; для этого я бы прибегнул к JSDoc.const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Вы можете использовать этот www.npmjs.com/package/sleep
источник
MacOS
, но он сталкивается с ошибкамиCentOS
из-за ошибок node_gyp . Кажется, не портативный.Этот вопрос довольно старый, но недавно V8 добавил генераторы, которые могут выполнять то, что запрашивал OP. Генераторы, как правило, проще всего использовать для асинхронных взаимодействий с помощью библиотеки, такой как suspend или gen-run .
Вот пример использования suspend:
Связанное чтение (путем бесстыдного саморекламы): какова большая сделка с генераторами? ,
источник
yield setTimeout(suspend.resume(), 10000);
--harmony
флагом, и, согласно node.green, они по крайней мере доступны без каких-либо флагов, начиная с v4.8.4: node.green/#ES2015-functions-generators-basic-functionality . Обратите внимание, однако, что новыйasync/await
синтаксис обеспечивает лучшее решение для этого сейчас, без необходимости в дополнительных библиотеках, таких какsuspend
. Посмотрите этот ответ для примера: stackoverflow.com/a/41957152/376789 . Асинхронные функции доступны (без флагов) начиная с версии 7.10.В Linux / nodejs это работает для меня:
Это блокировка, но это не занятый цикл ожидания.
Указанное вами время указывается в секундах, но может быть и долей. Я не знаю, есть ли в других ОС аналогичная команда.
источник
sleep
в значительной степени вездесущий и полезный с ранних дней UNIX en.wikipedia.org/wiki/Sleep_%28Unix%29 . Только «не редкость», о которой он, возможно, не существовал бы, это окна (как бы там ни было, вы можете попытатьсяchild_process.spawnSync('timeout', ['/T', '10'])
Если вы хотите «кодировать гольф», вы можете сделать сокращенную версию некоторых других ответов здесь:
Но на самом деле идеальный ответ, на мой взгляд, состоит в том, чтобы использовать
util
библиотеку Node и ееpromisify
функции, которые предназначены именно для такого рода вещей (создание версий на основе обещаний ранее существующих вещей, не основанных на обещаниях):В любом случае вы можете сделать паузу, просто
await
вызвав вашуsleep
функцию:источник
await
. Это своего рода создает обратный вызов, приостанавливает работу, а затем перезапускает код при возврате этого обратного вызова. Обратный вызов возвращается со значением, но в данном случае мы не заботимся об этом, поэтому слева от него ничего нетawait
.Недавно я создал более простую абстракцию под названием wait.for для вызова асинхронных функций в режиме синхронизации (на основе волокон узла). Существует также версия, основанная на будущих генераторах ES6.
https://github.com/luciotato/waitfor
Используя wait.for , вы можете вызывать любую стандартную асинхронную функцию nodejs, как если бы это была функция синхронизации, без блокировки цикла событий узла.
Вы можете кодировать последовательно, когда вам это нужно, что (я предполагаю) идеально подходит для упрощения ваших сценариев для личного использования.
используя wait.for ваш код будет:
Также любая асинхронная функция может быть вызвана в режиме синхронизации . Проверьте примеры.
источник
TypeError: Object #<Object> has no method 'miliseconds'
wait.for/paralell-tests.js
я обнаружил еще одну ошибку, связанную с неопределенными свойствами и т. д. Поэтому мне нужно было их тоже скопировать. Почему бы вам не организовать код таким образом, чтобы это не требовалось?Поскольку движок javascript (v8) выполняет код на основе последовательности событий в очереди событий, не существует строгого требования, чтобы javascript точно запускал выполнение в указанное время. То есть, когда вы устанавливаете несколько секунд для выполнения кода позже, запуск кода основывается исключительно на последовательности в очереди событий. Таким образом, запуск выполнения кода может занять больше указанного времени.
Итак, Node.js следует,
запустить код позже вместо setTimeout (). Например,
источник
С ES6, поддерживающими
Promise
s, мы можем использовать их без посторонней помощи.Тогда используйте это так:
Обратите внимание, что
doWhat
функция становитсяresolve
обратным вызовом внутриnew Promise(...)
.Также обратите внимание, что это асинхронный сон. Он не блокирует цикл обработки событий. Если вам нужна блокировка сна, используйте эту библиотеку, которая реализует блокировку сна с помощью привязок C ++. (Хотя потребность в блокировке сна в Node-среде, такой как асинхронная среда, встречается редко.)
https://github.com/erikdubbelboer/node-sleep
источник
Этот код выше является побочным эффектом решения проблемы адского асинхронного обратного вызова Javascript. Это также причина, по которой я думаю, что делает Javascript полезным языком в бэкэнде. На самом деле, на мой взгляд, это самое захватывающее улучшение, внесенное в современный Javascript. Чтобы полностью понять, как он работает, необходимо полностью понять, как работает генератор.
function
Ключевое слово сопровождаемое*
называется функцией генератора в современных JavaScript. Пакет npmco
предоставляет функцию runner для запуска генератора.По сути, функция генератора обеспечивает способ приостановить выполнение функции с
yield
ключевым словом, в то же времяyield
функция генератора позволяет обмениваться информацией между генератором и вызывающей стороной. Это предоставило вызывающему механизму механизм извлечения данныхpromise
из асинхронного вызова и передачи разрешенных данных обратно в генератор. По сути, это делает асинхронный вызов синхронным.источник
Это специализированный модуль moment.js, основанный на подходе грязной блокировки, предложенном @ atlex2 . Используйте это только для тестирования .
источник
Если вам просто нужно приостановить работу с целью тестирования вашего текущего потока, попробуйте это:
источник
Проще говоря, мы будем ждать 5 секунд, чтобы произошло какое-то событие (на что указывает переменная done, установленная в true где-то еще в коде), или по истечении времени ожидания мы будем проверять каждые 100 мс.
источник
Для некоторых людей принятый ответ не работает, я нашел этот другой ответ, и он работает для меня: как я могу передать параметр в функцию обратного вызова setTimeout ()?
'hello' - передаваемый параметр, вы можете передать все параметры по истечении времени ожидания. Спасибо @Fabio Phms за ответ.
источник
Вместо того, чтобы делать все эти setTimeout, sleep и многое другое, лучше использовать
источник
Другие ответы великолепны, но я подумал, что выберу другой такт.
Если все, что вы действительно ищете, это замедлить определенный файл в Linux:
узел myprog slowfile
Это будет спать 1 сек каждые пять строк. Программа узла будет работать так же медленно, как писатель. Если это делает другие вещи, они продолжат с нормальной скоростью.
Mkfifo создает канал «первым пришел - первым вышел». Это то, что делает эту работу. Строка Perl будет писать так быстро, как вы хотите. $ | = 1 говорит не буферизировать вывод.
источник
После прочтения ответов на этот вопрос я собрал простую функцию, которая также может выполнять обратный вызов, если вам это нужно:
источник
Для получения дополнительной информации о
Вы должны проверить Redux-Saga . Но это зависит от вашего выбора Redux в качестве вашей модели фреймворка (хотя строго не обязательно).
источник