How to set delay or interval inside map Promise? [duplicate] - javascript
I'm developing a console script for personal needs. I need to be able to pause for an extended amount of time, but, from my research, Node.js has no way to stop as required. It’s getting hard to read users’ information after a period of time... I’ve seen some code out there, but I believe they have to have other code inside of them for them to work such as:
setTimeout(function() {
}, 3000);
However, I need everything after this line of code to execute after the period of time.
For example,
// 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
I've also seen things like
yield sleep(2000);
But Node.js doesn't recognize this.
How can I achieve this extended pause?
Update Jan 2021: You can even do it in the Node REPL interactive using --experimental-repl-await flag
$ node --experimental-repl-await
> const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
> await delay(1000) /// waiting 1 second.
A new answer to an old question. Today ( Jan 2017 June 2019) it is much easier. You can use the new async/await syntax.
For example:
async function init() {
console.log(1);
await sleep(1000);
console.log(2);
}
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
For using async/await out of the box without installing and plugins, you have to use node-v7 or node-v8, using the --harmony flag.
Update June 2019: By using the latest versions of NodeJS you can use it out of the box. No need to provide command line arguments. Even Google Chrome support it today.
Update May 2020:
Soon you will be able to use the await syntax outside of an async function. In the top level like in this example
await sleep(1000)
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
The proposal is in stage 3.
You can use it today by using webpack 5 (alpha),
More info:
Harmony Flag in Nodejs: https://nodejs.org/en/docs/es6/
All NodeJS Version for download: https://nodejs.org/en/download/releases/
The shortest solution without any dependencies:
await new Promise(resolve => setTimeout(resolve, 5000));
Best way to do this is to break your code into multiple functions, like this:
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);
It's similar to JohnnyHK's solution, but much neater and easier to extend.
This is a simple blocking technique:
var waitTill = new Date(new Date().getTime() + seconds * 1000);
while(waitTill > new Date()){}
It's blocking insofar as nothing else will happen in your script (like callbacks). But since this is a console script, maybe it is what you need!
Put the code that you want executed after the delay within the setTimeout callback:
console.log('Welcome to My Console,');
setTimeout(function() {
console.log('Blah blah blah blah extra-blah');
}, 3000);
On Node 7.6.0 or higher
Node supports waiting natively:
const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs));
then if you can use async functions:
await sleep(10000); // sleep for 10 seconds
or:
sleep(10000).then(() => {
// This will execute 10 seconds from now
});
On older Node versions (original answer)
I wanted an asynchronous sleep that worked in Windows & Linux, without hogging my CPU with a long while loop. I tried the sleep package but it wouldn't install on my Windows box. I ended up using:
https://www.npmjs.com/package/system-sleep
To install it, type:
npm install system-sleep
In your code,
var sleep = require('system-sleep');
sleep(10*1000); // sleep for 10 seconds
Works like a charm.
Simple and elegant sleep function using modern Javascript
function sleep(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
No dependencies, no callback hell; that's it :-)
Considering the example given in the question, this is how we would sleep between two console logs:
async function main() {
console.log("Foo");
await sleep(2000);
console.log("Bar");
}
main();
The "drawback" is that your main function now has to be async as well. But, considering you are already writing modern Javascript code, you are probably (or at least should be!) using async/await all over your code, so this is really not an issue. All modern browsers today support it.
Giving a little insight into the sleep function for those that are not used to async/await and fat arrow operators, this is the verbose way of writing it:
function sleep(millis) {
return new Promise(function (resolve, reject) {
setTimeout(function () { resolve(); }, millis);
});
}
Using the fat arrow operator, though, makes it even smaller (and more elegant).
You can use this www.npmjs.com/package/sleep
var sleep = require('sleep');
sleep.sleep(10); // sleep for ten seconds
If you want to "code golf" you can make a shorter version of some of the other answers here:
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
But really the ideal answer in my opinion is to use Node's util library and its promisify function, which is designed for exactly this sort of thing (making promise-based versions of previously existing non-promise-based stuff):
const util = require('util');
const sleep = util.promisify(setTimeout);
In either case you can then pause simply by using await to call your sleep function:
await sleep(1000); // sleep for 1s/1000ms
EDIT: As noted in the comments, you can even reduce that to one line:
const sleep = require('util').promisify(setTimeout);
Or, if you don't even want to bother making a sleep function:
await require('util').promisify(setTimeout)(1000);
This question is quite old, but recently V8 has added Generators which can accomplish what the OP requested. Generators are generally easiest to use for async interactions with the assistance of a library such as suspend or gen-run.
Here's an example using 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');
})();
Related reading (by way of shameless self promotion): What's the Big Deal with Generators?.
From Node.js 15 and up you can use the Timers Promises API. You don't have to promisify setTimeout or rely on a 3rd party library anymore.
import { setTimeout } from 'timers/promises';
await setTimeout(1000);
On Linux/nodejs this works for me:
const spawnSync = require('child_process').spawnSync;
var sleep = spawnSync('sleep', [1.5]);
It is blocking, but it is not a busy wait loop.
The time you specify is in seconds but can be a fraction. I don't know if other OS's have a similar command.
Try using promise, it works for me in NodeJS
one liner
await new Promise(resolve => setTimeout(resolve, 5000));
or have it as a function in NodeJS to re-use
const sleep = async (milliseconds) => {
await new Promise(resolve => setTimeout(resolve, milliseconds));
}
use the function like
await sleep(5000)
I've recently created simpler abstraction called wait.for to call async functions in sync mode (based on node-fibers). There is also a version based on upcoming ES6 Generators.
https://github.com/luciotato/waitfor
Using wait.for, you can call any standard nodejs async function, as if it were a sync function, without blocking node's event loop.
You can code sequentially when you need it, which is, (I'm guessing) perfect to simplify your scripts for personal use.
using wait.for your code will be:
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.
Also any async function can be called in Sync mode.
Check the examples.
Since, javascript engine (v8) runs code based on sequence of events in event-queue, There is no strict that javascript exactly trigger the execution at after specified time. That is, when you set some seconds to execute the code later, triggering code is purely base on sequence in event queue. So triggering execution of code may take more than specified time.
So Node.js follows,
process.nextTick()
to run the code later instead setTimeout(). For example,
process.nextTick(function(){
console.log("This will be printed later");
});
Node 16 has a new way to do it easily
import { setTimeout } from 'timers/promises'
console.log('before')
await setTimeout(3000)
console.log('after')
With ES6 supporting Promises, we can use them without any third-party aid.
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.
Then use it like this:
const waitThenDo(howLong, doWhat) => {
return sleep(howLong).then(doWhat);
};
Note that the doWhat function becomes the resolve callback within the new Promise(...).
Also note that this is ASYNCHRONOUS sleep. It does not block the event loop. If you need blocking sleep, use this library which realizes blocking sleep with the help of C++ bindings. (Although the need for a blocking sleep in Node like async environments is rare.)
https://github.com/erikdubbelboer/node-sleep
In order to "wait" in javascript using promises are the way to go as the top answers show.
So how can it be used?
Here's a simple example of a 5-second sub-process queuing up parameters for a 4-second main process in a non-blocking manner.
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'))
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');
});
This code above is the side effect of the solving Javascript's asynchronous callback hell problem. This is also the reason I think that makes Javascript a useful language in the backend. Actually this is the most exciting improvement introduced to modern Javascript in my opinion. To fully understand how it works, how generator works needs to be fully understood. The function keyword followed by a * is called a generator function in modern Javascript. The npm package co provided a runner function to run a generator.
Essentially generator function provided a way to pause the execution of a function with yield keyword, at the same time, yield in a generator function made it possible to exchange information between inside the generator and the caller. This provided a mechanism for the caller to extract data from a promise from an asynchronous call and to pass the resolved data back to the generator. Effectively, it makes an asynchronous call synchronous.
This is a moment.js flavored module based on the dirty blocking approach suggested by #atlex2. Use this only for testing.
const moment = require('moment');
let sleep = (secondsToSleep = 1) => {
let sleepUntill = moment().add(secondsToSleep, 'seconds');
while(moment().isBefore(sleepUntill)) { /* block the process */ }
}
module.exports = sleep;
simple we are going to wait for 5 seconds for some event to happen (that would be indicated by done variable set to true somewhere else in the code) or when timeout expires that we will check every 100ms
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;
}
})();
For some people, the accepted answer is not working, I found this other answer and it is working for me: How can I pass a parameter to a setTimeout() callback?
var hello = "Hello World";
setTimeout(alert, 1000, hello);
'hello' is the parameter being passed, you can pass all the parameters after the timeout time. Thanks to #Fabio Phms for the answer.
function doThen(conditional,then,timer) {
var timer = timer || 1;
var interval = setInterval(function(){
if(conditional()) {
clearInterval(interval);
then();
}
}, timer);
}
Example usage:
var counter = 1;
doThen(
function() {
counter++;
return counter == 1000;
},
function() {
console.log("Counter hit 1000"); // 1000 repeats later
}
)
If you just need to suspend for testing purpose you current thread execution try this:
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
The other answers are great but I thought I'd take a different tact.
If all you are really looking for is to slow down a specific file in linux:
rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile &
node myprog slowfile
This will sleep 1 sec every five lines. The node program will go as slow as the writer. If it is doing other things they will continue at normal speed.
The mkfifo creates a first-in-first-out pipe. It's what makes this work.
The perl line will write as fast as you want. The $|=1 says don't buffer the output.
I put together, after having read the answers in this question, a simple function which can also do a callback, if you need that:
function waitFor(ms, cb) {
var waitTill = new Date(new Date().getTime() + ms);
while(waitTill > new Date()){};
if (cb) {
cb()
} else {
return true
}
}
For more info on
yield sleep(2000);
you should check Redux-Saga. But it is specific to your choice of Redux as your model framework (although strictly not necessary).
Related
Is it possible to tell if an async function is currently running at the top of the "program"?
I'm trying to do something that involves a global context that knows about what function is running at the moment. This is easy with single-threaded synchronous functions, they start off running and finish running when they return. But async functions can pop to the bottom of the program and climb back up multiple times before completing. let currentlyRunningStack: string[] = []; function run(id: string, cb: () => any) { currentlyRunningStack.push(id); cb() currentlyRunningStack.shift(); } // works with synchronous stuff run("foo", () => { run("bar", () => console.log("bar should be running")); console.log("now foo is running"); }); // can it work with asynchronous run("qux", async () => { // async functions never run immediately... await somePromise(); // and they start and stop a lot }); Is it possible to keep track of whether or not an asynchronous function is currently running or currently waiting on something? EDIT: there appears to be something similar called Zone.js. Used by Angular I guess. Something like async_hooks for the browser? EDIT: per #Bergi's suggestion, the word "stack" has been updated to "program" for clarification
It is possible, and someone has done it -- the angular developers, no less -- but it costs a whopping 5.41Mb!! https://www.npmjs.com/package/zone.js This was ripped from this very similar question: Something like async_hooks for the browser? In order to distinguish from that question a bit, I'll answer the core query here: Yes, you can tell when an async function stops and starts. You can see a lot of what's required in the project code In particular, this file appears to handle poly-filling promises, though I'd need more time to verify this is where the magic happens. Perhaps with some effort I can distill this into something simpler to understand, that doesn't require 5.41 Mb to acheive.
Yes, it possible. Using a running context, like a mutex, provided by Edgar W. Djiskistra, stack queues, Promise states and Promise.all executor. This way you can keep track if there's a running function in the program. You will have to implement a garbage collector, keeping the mutex list clean and will need a timer(setTimeout) to verify if the context is clean. When the context is clean, you will call a callback-like function to end you program, like process.exit(0). By context we refeer to the entire program order of execution. Transforming the function into a promise with an .then callback to pop/clean the stack of the mutex after the execution of content of the function with a try/catch block to throw, handle, or log errors add more control to the hole program. The introduction of setTimeout propicies a state machine, combined with the mutex/lock and introduces a memory leak that you will need to keep track of the timer to clear the memory allocated by each function. This is done by neste try/catch. The use of setInterval for it introduces a memory leak that will cause a buffer overflow. The timer will do the end of the program and there's it. You can keep track if a function is running or not and have every function registered running in a syncrhonous manner using await with and mutex. Running the program/interpreter in a syncrhonous way avoid the memory leaks and race conditions, and work well. Some code example below. const async run (fn) => { const functionContextExecutionStackLength = functionExecutionStackLength + 1 const checkMutexStackQueue = () => { if (mutexStack[0] instanceof Promise) { if (mutex[0].state == "fullfiled") { mutexStack = mutexStack.split(1, mutexStack.length) runner.clear() runner() } } if (mutexStack.length == 0) process.exit(0) } // clear function Exection Context const stackCleaner = setTimeout(1000, (err, callback) => { if (functionContextExecutionStackLength == 10) { runner.clear() } }) stackCleaner = stackCleaner() // avoid memory leak on function execution context if (functionContextExecutionStackLength == 10) { stackCleaner.clear() stackCleaner() } // the runner const runner = setTimeout(1, async (err, callback) => { // run syncronous const append = (fn) => mutex.append(util.promisfy(fn) .then(appendFunctionExectionContextTimes) .then(checkMutexStackQueue)) // tranaform into promise with callback const fn1 = () => util.promify(fn) const fn2 = () => util.promisfy(append) const orderOfExecution = [fn1, fn2, fn] // a for await version can be considered for (let i = 0; i < orderOfExecution.length; i++) { if (orderOfExecution.length == index) { orderOfExecution[orderOfExecution.length]() } else { try { orderOfExecution[i]() } catch (err) { throw err console.error(err) } } } } } (() => run())(fn) On the code above we take the assynchronous caracterisc of javascript very seriously. Avoiding it when necessary and using it when is needed. Obs: Some variables was ommited but this is a demo code. Sometimes you will see a variables context switching and call before execution, this is due to the es modules characteriscts of reading it all and interpreting it later.
JavaScript: what type of functions can we create to be executed asynchronously?
I’m trying to understand how async functions work in JavaScript and how to write them, but it seems to me that the way the language handles async functions is pretty limited, but I can be wrong and, probably, I did not understand it. I use Visual Studio Code (v. 1.66.2) and Chrome (v 100.0.4896.88) on Windows 10 X64. Just for experimental purposes, I wrote a simple heavyLoad() function that gets a delay parameter (that represents a millisecond value) and return true after time elapsed: function heavyLoad(delay) { let startTime = (new Date()).getTime(); while(new Date().getTime() < startTime + delay); return true; } If I write: heavyLoad(5000); console.log(“Hello”); the console.log() function is, obviously, executed after 5 secs, since I have to wait that heavyLoad() function ends. I’m trying to make heavyLoad() function as asynchronous so that I can read, in the browser console, Hello immediately without waiting for heavyLoad() function but I’m not able to do that: I’ve tried to create a promise object; I tried to use async keyword but nothing works, since I have always to wait that heavyLoad() function ends before reading Hello. Is it possible to make heavyLoad() function, essentially as it is, an async one as I meant?
You can use WebWorker and Promise Write your heavy load script in a separate file. worker.js onmessage = function(e) { let startTime = (new Date()).getTime(); while(new Date().getTime() < startTime + e.data); postMessage(true); } Run that webWorker in the main script file. main.js function heavyLoad(delay) { return new Promise((resolve, reject) => { var myWorker = new Worker('worker.js'); myWorker.postMessage(delay); myWorker.addEventListener('message', function(e) { // Log the workers message. resolve(e.data); }, { once: true }); }) } console.log("Starting") console.time() heavyLoad(5000).then(data=>{ console.timeEnd() }) console.log("end") (Here I'm using console.time method to keep track of the execution time)
For timeout there is setTimeout() method in javascript. So you can simply use: setTimeout(() => { console.log("Hello"); }, 5000);
Try following code to understand asynchronous working function heavyLoad(delay) { return new Promise((resolve, reject)=>{ setTimeout(()=>{ resolve(true) },delay) }) } heavyLoad(5000).then(value=>{ console.log(value) }); console.log("Hello"); It will print hello first as you run the code and true after 5 seconds.
You have to Use Settimeout function as you want to delay the function as long as you want and also setTimeout will act as asynchronous so you will log out hello immediately function heavyLoad(delay) { setTimeout(() => { return true },delay); } heavyLoad(5000); console.log("hello");
How To Stop An Infinite Loop in Node.js/Javascript
If we started 2 concurrent infinite loops using worker('hello') and worker('world'), how can we later stop one of the loops? For example: const sleep = async function (duration) { await new Promise(r => setTimeout(r, duration)); } const worker = async (id) => { while (true) { console.log(id); await sleep(2000); // simulates a blocking call } } (async () => { const hello = worker('hello') const world = worker('world') // Let's assume that now a user-input requires us to stop the `worker('hello')` setTimeout(() => { console.log('stopping hello...')\ // how to stop 'hello'? }, 5000) })();
You cannot stop those worker() loops from outside of the function. Javascript does not have that capability. You would need those loops to be checking something that is outside the loop (a variable or calling a function or something like that) for you to be able to influence them. There are many other ways to write the loop that can be influenced from the outside world. Some examples: Use setInterval() and return the interval timerID from the function. Then, you can call clearInterval() to stop the loop. Create a small object where your loop is one method and have that loop test an instance variable that you can change from the outside. P.S. There might be some hacks where you replace Promise with a constructor that would force a reject which would cause the await to throw and then containing async function to reject on the next cycle, but I assume you're not looking for that level of hack and invasion of the environment. Since sleep() is declared as const you can't hack in a replacement for it that would reject.
If the only thing you want to do with the worker function is to repeat some action every N milliseconds, I suggest using setInterval explained here function worker(id) { return setInterval(() => {//loop actions inside this annonymous function console.log(id); //Anything else }, 2000);//Every 2000 milliseconds } //make a loop active const intervalHello = worker(`Hello`); //stop the interval clearInterval(intervalHello);
What is the best way to call a asynchronous Function in Javascript(Angular) with some delay/sleep. Setimeout doesn't allow to do the same [duplicate]
Similar to this question, but rather than asking about how promises work in general, I specifically want to know: What is the standard/best way to wrap setTimeout in something that returns a Promise? I'm thinking something like Angular's $timeout function, but not Angular specific.
In Browsers First of all no - there is no built in for this. Lots of libraries that enhance ES2015 promises like bluebird whip with it. I think the other answer conflates executing the function and a delay, it also creates timeouts that are impossible to cancel. I'd write it simply as: function delay(ms){ var ctr, rej, p = new Promise(function (resolve, reject) { ctr = setTimeout(resolve, ms); rej = reject; }); p.cancel = function(){ clearTimeout(ctr); rej(Error("Cancelled"))}; return p; } Then you can do: delay(1000).then(/* ... do whatever */); Or doSomething().then(function(){ return delay(1000); }).then(doSomethingElse); If we only want the basic functionality in ES2015, it's even simpler as: let delay = ms => new Promise(r => setTimeout(r, ms)); In Node You can use util.promisify on setTimeout to get a delay function back - meaning you don't have to use the new Promise constructor anymore.
Here's how I'd implement it: function delay(duration, func) { var args = Array.prototype.slice.call(arguments, 2); return new Promise(function (resolve) { setTimeout(function () { resolve(func.apply(null, args)); }, duration); }); } (ES5-syntax intentionally chosen) But maybe there's a common library that already does this, or a better way to do it.
If you need the proper cancellation of promised timeout similar to clearTimeout - returning the promise directly from setTimeout is not convenient. Especially when using with ES7 async / await in try...finally block. It is better to have separate variable for timeout manipulation. I've implemented this approach as tiny await-timeout package. It works as following: import Timeout from 'await-timeout'; async function foo() { const timeout = new Timeout(); try { const fetchPromise = fetch('https://example.com'); const timerPromise = timeout.set(1000).then(() => console.log('Timeout!')); await Promise.race([fetchPromise, timerPromise]); } finally { timeout.clear(); } } In this example timeout will definitely be cleared in case of fetch success or any error and console.log('Timeout!') will not be called.
How can I wait In Node.js (JavaScript)? l need to pause for a period of time
I'm developing a console script for personal needs. I need to be able to pause for an extended amount of time, but, from my research, Node.js has no way to stop as required. It’s getting hard to read users’ information after a period of time... I’ve seen some code out there, but I believe they have to have other code inside of them for them to work such as: setTimeout(function() { }, 3000); However, I need everything after this line of code to execute after the period of time. For example, // 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 I've also seen things like yield sleep(2000); But Node.js doesn't recognize this. How can I achieve this extended pause?
Update Jan 2021: You can even do it in the Node REPL interactive using --experimental-repl-await flag $ node --experimental-repl-await > const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) > await delay(1000) /// waiting 1 second. A new answer to an old question. Today ( Jan 2017 June 2019) it is much easier. You can use the new async/await syntax. For example: async function init() { console.log(1); await sleep(1000); console.log(2); } function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } For using async/await out of the box without installing and plugins, you have to use node-v7 or node-v8, using the --harmony flag. Update June 2019: By using the latest versions of NodeJS you can use it out of the box. No need to provide command line arguments. Even Google Chrome support it today. Update May 2020: Soon you will be able to use the await syntax outside of an async function. In the top level like in this example await sleep(1000) function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } The proposal is in stage 3. You can use it today by using webpack 5 (alpha), More info: Harmony Flag in Nodejs: https://nodejs.org/en/docs/es6/ All NodeJS Version for download: https://nodejs.org/en/download/releases/
The shortest solution without any dependencies: await new Promise(resolve => setTimeout(resolve, 5000));
Best way to do this is to break your code into multiple functions, like this: 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); It's similar to JohnnyHK's solution, but much neater and easier to extend.
This is a simple blocking technique: var waitTill = new Date(new Date().getTime() + seconds * 1000); while(waitTill > new Date()){} It's blocking insofar as nothing else will happen in your script (like callbacks). But since this is a console script, maybe it is what you need!
Put the code that you want executed after the delay within the setTimeout callback: console.log('Welcome to My Console,'); setTimeout(function() { console.log('Blah blah blah blah extra-blah'); }, 3000);
On Node 7.6.0 or higher Node supports waiting natively: const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs)); then if you can use async functions: await sleep(10000); // sleep for 10 seconds or: sleep(10000).then(() => { // This will execute 10 seconds from now }); On older Node versions (original answer) I wanted an asynchronous sleep that worked in Windows & Linux, without hogging my CPU with a long while loop. I tried the sleep package but it wouldn't install on my Windows box. I ended up using: https://www.npmjs.com/package/system-sleep To install it, type: npm install system-sleep In your code, var sleep = require('system-sleep'); sleep(10*1000); // sleep for 10 seconds Works like a charm.
Simple and elegant sleep function using modern Javascript function sleep(millis) { return new Promise(resolve => setTimeout(resolve, millis)); } No dependencies, no callback hell; that's it :-) Considering the example given in the question, this is how we would sleep between two console logs: async function main() { console.log("Foo"); await sleep(2000); console.log("Bar"); } main(); The "drawback" is that your main function now has to be async as well. But, considering you are already writing modern Javascript code, you are probably (or at least should be!) using async/await all over your code, so this is really not an issue. All modern browsers today support it. Giving a little insight into the sleep function for those that are not used to async/await and fat arrow operators, this is the verbose way of writing it: function sleep(millis) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, millis); }); } Using the fat arrow operator, though, makes it even smaller (and more elegant).
You can use this www.npmjs.com/package/sleep var sleep = require('sleep'); sleep.sleep(10); // sleep for ten seconds
If you want to "code golf" you can make a shorter version of some of the other answers here: const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); But really the ideal answer in my opinion is to use Node's util library and its promisify function, which is designed for exactly this sort of thing (making promise-based versions of previously existing non-promise-based stuff): const util = require('util'); const sleep = util.promisify(setTimeout); In either case you can then pause simply by using await to call your sleep function: await sleep(1000); // sleep for 1s/1000ms EDIT: As noted in the comments, you can even reduce that to one line: const sleep = require('util').promisify(setTimeout); Or, if you don't even want to bother making a sleep function: await require('util').promisify(setTimeout)(1000);
This question is quite old, but recently V8 has added Generators which can accomplish what the OP requested. Generators are generally easiest to use for async interactions with the assistance of a library such as suspend or gen-run. Here's an example using 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'); })(); Related reading (by way of shameless self promotion): What's the Big Deal with Generators?.
From Node.js 15 and up you can use the Timers Promises API. You don't have to promisify setTimeout or rely on a 3rd party library anymore. import { setTimeout } from 'timers/promises'; await setTimeout(1000);
On Linux/nodejs this works for me: const spawnSync = require('child_process').spawnSync; var sleep = spawnSync('sleep', [1.5]); It is blocking, but it is not a busy wait loop. The time you specify is in seconds but can be a fraction. I don't know if other OS's have a similar command.
Try using promise, it works for me in NodeJS one liner await new Promise(resolve => setTimeout(resolve, 5000)); or have it as a function in NodeJS to re-use const sleep = async (milliseconds) => { await new Promise(resolve => setTimeout(resolve, milliseconds)); } use the function like await sleep(5000)
I've recently created simpler abstraction called wait.for to call async functions in sync mode (based on node-fibers). There is also a version based on upcoming ES6 Generators. https://github.com/luciotato/waitfor Using wait.for, you can call any standard nodejs async function, as if it were a sync function, without blocking node's event loop. You can code sequentially when you need it, which is, (I'm guessing) perfect to simplify your scripts for personal use. using wait.for your code will be: 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. Also any async function can be called in Sync mode. Check the examples.
Since, javascript engine (v8) runs code based on sequence of events in event-queue, There is no strict that javascript exactly trigger the execution at after specified time. That is, when you set some seconds to execute the code later, triggering code is purely base on sequence in event queue. So triggering execution of code may take more than specified time. So Node.js follows, process.nextTick() to run the code later instead setTimeout(). For example, process.nextTick(function(){ console.log("This will be printed later"); });
Node 16 has a new way to do it easily import { setTimeout } from 'timers/promises' console.log('before') await setTimeout(3000) console.log('after')
With ES6 supporting Promises, we can use them without any third-party aid. 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. Then use it like this: const waitThenDo(howLong, doWhat) => { return sleep(howLong).then(doWhat); }; Note that the doWhat function becomes the resolve callback within the new Promise(...). Also note that this is ASYNCHRONOUS sleep. It does not block the event loop. If you need blocking sleep, use this library which realizes blocking sleep with the help of C++ bindings. (Although the need for a blocking sleep in Node like async environments is rare.) https://github.com/erikdubbelboer/node-sleep
In order to "wait" in javascript using promises are the way to go as the top answers show. So how can it be used? Here's a simple example of a 5-second sub-process queuing up parameters for a 4-second main process in a non-blocking manner. 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'))
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'); }); This code above is the side effect of the solving Javascript's asynchronous callback hell problem. This is also the reason I think that makes Javascript a useful language in the backend. Actually this is the most exciting improvement introduced to modern Javascript in my opinion. To fully understand how it works, how generator works needs to be fully understood. The function keyword followed by a * is called a generator function in modern Javascript. The npm package co provided a runner function to run a generator. Essentially generator function provided a way to pause the execution of a function with yield keyword, at the same time, yield in a generator function made it possible to exchange information between inside the generator and the caller. This provided a mechanism for the caller to extract data from a promise from an asynchronous call and to pass the resolved data back to the generator. Effectively, it makes an asynchronous call synchronous.
This is a moment.js flavored module based on the dirty blocking approach suggested by #atlex2. Use this only for testing. const moment = require('moment'); let sleep = (secondsToSleep = 1) => { let sleepUntill = moment().add(secondsToSleep, 'seconds'); while(moment().isBefore(sleepUntill)) { /* block the process */ } } module.exports = sleep;
simple we are going to wait for 5 seconds for some event to happen (that would be indicated by done variable set to true somewhere else in the code) or when timeout expires that we will check every 100ms 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; } })();
For some people, the accepted answer is not working, I found this other answer and it is working for me: How can I pass a parameter to a setTimeout() callback? var hello = "Hello World"; setTimeout(alert, 1000, hello); 'hello' is the parameter being passed, you can pass all the parameters after the timeout time. Thanks to #Fabio Phms for the answer.
function doThen(conditional,then,timer) { var timer = timer || 1; var interval = setInterval(function(){ if(conditional()) { clearInterval(interval); then(); } }, timer); } Example usage: var counter = 1; doThen( function() { counter++; return counter == 1000; }, function() { console.log("Counter hit 1000"); // 1000 repeats later } )
If you just need to suspend for testing purpose you current thread execution try this: 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
The other answers are great but I thought I'd take a different tact. If all you are really looking for is to slow down a specific file in linux: rm slowfile; mkfifo slowfile; perl -e 'select STDOUT; $| = 1; while(<>) {print $_; sleep(1) if (($ii++ % 5) == 0); }' myfile > slowfile & node myprog slowfile This will sleep 1 sec every five lines. The node program will go as slow as the writer. If it is doing other things they will continue at normal speed. The mkfifo creates a first-in-first-out pipe. It's what makes this work. The perl line will write as fast as you want. The $|=1 says don't buffer the output.
I put together, after having read the answers in this question, a simple function which can also do a callback, if you need that: function waitFor(ms, cb) { var waitTill = new Date(new Date().getTime() + ms); while(waitTill > new Date()){}; if (cb) { cb() } else { return true } }
For more info on yield sleep(2000); you should check Redux-Saga. But it is specific to your choice of Redux as your model framework (although strictly not necessary).