Table of Contents
Technical background of wait/delay/sleep
Programmers who have been coding in PHP or C# can look in JavaScript for functions like wait or sleep or delay. Functions like that just freeze running application in certain place for a given time and, next, continue code execution from that place. But in JavaScript there are no built-in methods like that! We can’t simply stop running application for a while.
But there are good workarounds that can help us to create wait/sleep/delay function in JavaScript. Without using any third-party libraries of course, just pure JavaScript!
Worth explain is why JavaScript does not have native functions like wait or sleep or delay functions. The reason is that JavaScript is a single-threaded language. So wait/delay/sleep function in JavaScript would freeze whole application for given time and no interaction with user would be then possible. But strong advantage of JavaScript is its possibility to run and resolve asynchronous operations.
All asynchronous operations are stored in event loop mechanism, you can read more about here on mdn
In this example of how to create wait or sleep or delay functions in JavaScript on our own. We will use here asynchronous nature of JavaScript.
I prepared 3 examples, two for all modern browsers (using ES2017 functions) and one for a very old browsers like Internet Explorer (using only ES5 functions).
JavaScript WAIT – SetTimeout function? Is it a good idea?
When we code in JavaScript than first idea to make a wait function is to use setTimeout. This is not a stupid idea, but all further code you will need to keep also in setTimeout callback.
So simply from normal synchronous code you will trigger asynchronously a callback function by setTimeout. Every action further must be taken also in this callack function.
This can look like following code – read comments and check image and GIF film below:
function wait5sec () {
var x = 5;
var y = 10;
var result = null;
setTimeout(function () { // asynchronous operation - will be queued in event loop after 5 seconds, but code after seTimeout runs immediately
result = x + y;
console.log(result); // will log result = 15 after 5 seconds wait
}, 5000);
// normal synchronous code IS NOT WAITING for setTimeout method. It goes in parallel.
return result; // will give result = null
}
So what we can see above – setTimeout function just by itself, doesn’t work like a real wait/delay/sleep in JavaScript. It only invokes callback function (first parameter of setTimeout()) and works as a JavaScript closure (callback has access into the scope (variables) from parent method – read more about JS closures on MDN here).
But usage of setTimeout() is a good idea, but… we can’t here return a proper value from this function. SetTimeout callback function runs later in time and there is no possibility to return value from this into the main function scope. To create real JavaScript wait function we need to enrich above solution with ASYNC/AWAIT functionality (ES2017). Read more to see that.
JavaScript WAIT function examples (promises + async/await)
We need to combine setTimeout function with 2 built-in JavaScript features:
Promise– custom made asynchronous operations (ES2015 standard),async/await– syntactic sugar for promises – using that we can retrieve response value from promise like in standard synchronous operation, just by putting await before promise function (standard ES2017)
Basic example of JavaScript wait function
Let’s start here from the sum function with JavaScript wait:
function wait (waitTime) {
return new Promise((resolve) => {// promise will be returned and used with async/await function
setTimeout(() => {
console.log('wait finished');
resolve(true); // when time will pass, than resolve promise
}, waitTime); // set wait time in miliseconds
});
}
async function sum (value, addValue) { EXAMPLE OF USAGE
// put here whatever code you want
await wait(5000); // stop for 5 seconds here
// put here whatever code you want
const sum = value + addValue;
return sum;
}WAIT function explanation – long story short:
- when
setTimeoutis executed then promise is resolved.
Detailed explanation:
waitis anasyncfunction. Argument:waitTimefor how long delay should last- Return
Promise. - Inside promise, the
setTimeoutfunction is declared wherewaitTimeis a delay argument. - Inside
setTimeout, thepromiseis sesolved. - Remember,
sumfunction will return aPromise(asasyncfunctions always return aPromise), but when you use that in another function, also withasync/awaitthan it will return wanted value after given wait time.
Usage explanation – long story short – SUM function example explanation:
sumis anasyncfunction- inside it a
waitfunction is triggered withawaitstatement. - By
awaitstatement code stops here tillPromiseis resolved - Code is executed further
Run this example below:
JavaScript WAIT 5 sec in FOR loop (promises + async/await)
This basic example leads us to more sophisticated one. Short story as introduction first 🙂
Let’s follow the above example with sum function, but now in for loop. Here WAIT will last 5 seconds.
As you can see in code below, the beginning is the same like in example above, the only difference is a way how to trigger sum function.
function wait5sec (waitTime) {
return new Promise((resolve) => {
setTimeout(() => {
console.log('wait finished');
resolve(true);
}, waitTime);
});
}
async function sum (value, addValue) {
await wait5sec(5000); // wait function - 5000 ms
return value + addValue;
}
async function runLoop() {
const initValue = 10;
for (let i = 0; i < 3; i++) {
const result = await sum(initValue, 10 * (i + 1));
console.log(results);
}
}WAIT 5 sec function in FOR loop explanation – long story short:
runLoopfunction isasyncandsumfunction invoked insideforisawait.
Detailed explanation:
sumfunction will always wait 5 seconds when triggered (bywait5secfunction)sumfunction isasyncfunction, so it returns in reality aPromiserunLoopfunction must also beasyncwithawaitstatement beforesumfunction (which will wait always 5 seconds)- Each run through
forloop make a pause there for 5 seconds (insum) and run next loop.
The most important in JavaScript WAIT 5 seconds in for loop example here is runLoop function.
Of course, this is just example, in real code you will run this wait function in for loop wherever needed, like AJAX requests (examples at the end of this article).
JavaScript WAIT recurrent function (old browsers, ES5)
Recurrent solution for wait function is good when you can’t use modern JavaScript code (presented above) based on Promises and async/await.
Recurrent wait function will work in all kinds of old browsers like Internet Explorer 11.
Check code below and its explanation. In recurrent wait function I still continue the example of sum function, which simply adds 10 to initially given value.
function recurrentLoopFunc (count, timeoutTime, seqCounter, callback) {
if (seqCounter < count) {
setTimeout(() => {
callback(seqCounter);
seqCounter++;
recurrentLoopFunc(count, timeoutTime, seqCounter, callback);
}, timeoutTime);
}
}
function runRecurrentLoop() {
var initValue = 10;
var result = 0;
recurrentLoopFunc(3, 5000, 0, function (i) {
result = initValue + 10 * (i + 1);
console.log(result);
});
}Recurrent wait function explanation – long story short:
recurentLoopFuncfunction triggers itself insidesetTimeoutfunction. We pass via callback function the operations to be done in sequence after given time.
Detailed explanation:
recurentLoopFuncworks in loop limited bycountparameter (how many times loop should be triggered) which is checked inifstatement in the very beginning.seqCounterparameter gives the initial integer number to start counting loops number.timeoutTimeparam sets what is thewaittime in between steps of sequence.callbackfunction passed as param is doing the main operation in given time sequence.- in
runRecurentLoopfunction we define most important things, so the whole procedure which we want to trigger in a time sequence. In this case we are using a JavaScript closure. So in outer scope we define theinitValueandresultvariables, on which further we do some math operations incallbackfunction passed intorecurentLoopFuncfunction.
Summary of wait with SUM function example
I described above the example of SUM function which I triggered in 3 scenarios – single wait, wait in for loop and wait in recurrent function.
You can find code of all 3 scenarios in above examples or:
Here you can find examples of all 3 scenarios of sum function gathered in one place, as a summary:
Real life examples of JavaScript wait function
Above example of sum function is a very basic one and can’t show the full power of wait function in JavaScript.
The full power of JavaScript WAIT function comes with the real life situation:
I was working some time ago on a small project where my NodeJS application was requesting the Open Street Map REST API for data. This is an open API, so it has limitation and it is not possible to make at once a few requests for big data sets. I needed to make every AJAX request at least 2 minutes after the previous one.
Demo API to simulate real AJAX requests with WAIT
I created “real life example of JavaScript wait function” with a very basic REST API.
We can request for a “products” with computer’s components and API returns it as a JSON, like below:
{
"index": 1,
"price": 138,
"product": "cpu",
"owner": "MULTRON"
}
The purpose of this example is to make request to REST API in a sequence with delay time between each requests.
This real life examples I will explain in shorter way. Generally the basics are the same like in above sum function, only usage is a little different.
Basic example of JavaScript wait in ajax REST API requests (ES2017)
In this example we simply trigger a single AJAX request to REST API once, with delay of 5 seconds.
Please, remember that this code will not work just like that if you copy-paste to your local application because of browser’s CORS policy. But you can run our example below.
You can explore code of our examples on Dev-Bay.com GitHub HERE – wait5sec.html and wait-5-sec.js.
function wait5sec() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, 5000);
});
}
async function callAPI(i) {
await wait5sec(); // wait function
const res = await fetch(`https://dev-bay.com/examples/php-api-js-wait/orders/${i}`);
return res.json();
}
async function runWait5sec() {
const result = await callAPI(1);
console.log(result);
}
runWait5sec();JavaScript wait in ajax REST API requests in FOR loop (ES2017)
This is a more real life example of usage the JavaScript wait. This situation occurs often when you need to request REST API with many requests when every contains a lot of data. Than you can’t overload the API server with too many requests at one moment, so you must make a delay between each one. And delay must be between previous request response and the following new request call.
You can explore code of our examples on Dev-Bay.com GitHub HERE – wait5sec-in-for-loop.html and wait-5-sec-in-loop.js.
function wait5sec() {
return new Promise((resolve) => {
setTimeout(() => {
console.log('wait finished');
resolve(true);
}, 5000);
});
}
async function callAPI(i) {
await wait5sec(); // wait function
const res = await fetch(`https://dev-bay.com/examples/php-api-js-wait/orders/${i}`);
return res.json();
}
async function runLoop() {
for (let i = 1; i < 4; i++) {
const result = await callAPI(i);
console.log(result);
}
}JavaScript wait in ajax REST API requests in recurrent function
This example of JS wait function with REST API call, the same like in sum function example above, is made in EcmaScript5 standard, so it means that it will work properly also in a very old browsers, like Internet Explorer 11.
This example, the same like above one in for loop, is designed to be used in situations when you need to request REST API with many requests when every contains a lot of data. Than you can’t overload the API server, so you must make a delay between each requests. And delay must be between previous request response and the following new request call.
You can explore code of our examples on Dev-Bay.com GitHub HERE – wait5sec-in-recurent-func.html and recurent-wait.js.
function recurentLoopFunc(count, timeoutTime, seqCounter, callback) {
if (seqCounter < count) {
setTimeout(() => {
callback(seqCounter).then(function (response) {
return response.json();
}).then(function (result) {
console.log(result);
seqCounter++;
recurentLoopFunc(count, timeoutTime, seqCounter, callback);
});
}, timeoutTime);
}
}
function runWait5secInRecurentLoop(i) {
recurentLoopFunc(4, 5000, 1, function (i) {
return fetch(`https://dev-bay.com/examples/php-api-js-wait/orders/${i}`);
});
}
JavaScript wait – summary
As you can see from all above examples, it is possible to implement in JavaScript the wait (or delay/sleep) function that will behave more or less the same like in other programming languages. It is the best to use my solution with ES2017 standard, so with promises and async/await because this solutions gives the best experience to use in the code.
For other browsers still you can use solution created with only ES5 standard so by recurrent function and callback function triggered inside it.
I hope that my work will be helpful for you 🙂 Enjoy!