setTimeout wait to execute what's after - javascript

I want to know how to make setTimeout wait before executing what comes after.
setTimeout( function() { console.log("First"); }, 5000 );
console.log("Second");
In the console I want to see:
First
Second
"First" after 5 seconds and then "Second" just after "First"
But what's really happening is that I have "Second" and after 5 seconds "First"
How can this be fixed ?

If IE is not priority and you allowed to use Promise, then you can use a simple wait function to work as setTimeout and return Promisewhich allows for method chaining:
function wait(t) {
return new Promise(function(resolve) {
window.setTimeout(resolve, t)
});
}
wait(5000)
.then(function(){ console.log("First"); })
.then(function(){ console.log("Second"); });

setTimeout( function() { console.log("First"); }, 1000 );
setTimeout( function() { console.log("Second"); }, 1000 );

Javascript does not guarantee linear order of execution in your code. You can't expect your code to execute line by line when introducing timeouts or asynchronous tasks.
You could print both lines within the resolving function:
setTimeout(function() {
console.log("First");
console.log("Second");
}, 5000);

If you are executing more than just a console log after, you can write a new function to run after the setTimeout. Anything in the "second" function will occur after logging "First".
var second = function () {
console.log("Second");
}
setTimeout( function() {
console.log("First");
second();
}, 5000 );

I want to know how to make setTimeout wait before executing what comes after.
I think the JavaScript function for "wait" is setTimeout. Meaning you can achieve this by nesting one setTimeout function inside another.
setTimeout(function() {
setTimeout(function() {
console.log('Second');
}, 100);
console.log('First');
}, 5000);

Related

How to use call back to make a function execute after another in setTimeout condition

I have some code which can be mimicked by this situation
function abc(def){
setTimeout(1500,function(){
console.log('1');
}
def();
}
function def(){
console.log('2'}
}
I want 2 to be printed after 1 - how do I do that?
If you want a function to also be called after a delay... just put it inside the delay. I've added some extra console logs and fixed some of your code. Run the below example to see how it works.
function def() {
console.log('2 - def()');
}
function abc() {
console.log('before');
setTimeout(function() {
console.log('1');
def();
}, 1500);
console.log('after');
}
abc();
function abc(def){
setTimeout(1500,function(){
console.log('1');
def();
}
}
You can use async and await. Wrap the setTimeout(...) in a Promise and resolve Promise inside the callback passed to setTimeout.
async function abc(def){
await new Promise(res => {
setTimeout(function(){
console.log('1');
res();
},1500)
})
def();
}
function def(){
console.log('2')
}
abc(def)
setTimeout(function, milliseconds) takes a function has the first parameter and delay value (time in milliseconds) as the second parameter. You were passing them in the wrong order.
Also in your example def() was printing 2 and it was outside the setTimeout function, so it could not have possibly printed 2 after 1 (as 1 was being logged inside the setTimeout, which means it would be executed after the delay of 1.5 seconds).
The solution provided by Chris above is correct and would do what you wanted (print 2 and then 1)

Fix error when trying to rewrite callback example to a promise

I'm trying to understand callbacks and promises using very simple examples. I figured out how to rewrite an example of why you need callbacks into a working "callback form". However, I'm stuck on rewriting this into a promise
I have tried to make this work as a promise following the example here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Basic_Example
But I'm having some trouble making it work.
First I got this code showing why callbacks are important:
function first(){
// Simulate a code delay
setTimeout( function(){
console.log(1);
}, 500 );
}
function second(){
console.log(2);
}
first();
second();
I then rewrote this using callbacks:
function first(callback){
// Simulate a code delay
setTimeout( function(){
console.log(1);
callback();
}, 500 );
}
function second(){
console.log(2);
}
first(second);
// second();
Now I'm wondering how to rewrite this as a promise.
let first = new Promise( function (resolve, reject){
// Simulate a code delay
setTimeout( function(){
console.log(1);
resolve('success')
}, 500 );
});
function second(){
console.log(2);
}
first.then(second());
What I want it to output is first 1 and then 2, now it ouputs 2, then 1.
this is the code that should do what you're asking.
The problem in your code is that you're actually calling second() immediately:
first.then(second());
instead of passing the function as the argument (then() will call it when the first promise is resolved):
let first = new Promise( function (resolve, reject){
// Simulate a code delay
setTimeout( function(){
console.log(1);
resolve('success')
}, 500 );
});
function second(){
console.log(2);
}
first.then(second);

JavaScript CallBack Function ..ish issue

So I was doing some practice about callback function and I wanted to try it out in my own was and use it with a setTimeout Method and to my surprise, it didn't work as expected.. Pls what am i doing wrong here.
function first(number, callback) {
setTimeout(function() {
console.log(number);
}, 5);
callback();
}
function second() {
console.log(2);
}
first(1, second);
You're executing setTimeout and callback at the same time. Because JavaScript is single-threaded, it doesn't wait for setTimeout to complete before executing the next statement.
That's why, 2 prints immediately, and then 1 prints after a delay of 5 milliseconds.
If you want to print 1 first, then you need to call the callback function in the callback of setTimeout. This ensures that the console.log(number) executes prior to calling the callback (which prints 2).
function first(number, callback) {
setTimeout(function() {
console.log(number);
callback();
}, 5);
}
function second() {
console.log(2);
}
first(1, second);
As 31piy already said, setTimeout() and callback() are being executed at the same time. Your code first schedules a function execution at 5ms from now, and then immediately runs another function that logs 2 to the console.
You can achieve the expected result in a couple of similar ways, I'll show one:
function first(number,callback) {
setTimeout(function() {
callback();
}, 5);
console.log(number);
}
function second() {
console.log(2);
}
first(1, second);
//Here, you immediately print the number 1 and schedule the number 2.

setTimeout wait for setTimeout

I stumbled upon a problem:
the code is supposed to output "hi1" "hi2" "hi3" "hi4" in that order.
I wrote this simplified code, the actual code is more complicated and causes me to not be able to remove some of the functions I marked.
function test() {
console.log("hi2");
setTimeout(function () { //maybe replace this?
console.log("hi3");
}, 2000);
}
console.log("hi1");
test();
setTimeout(function () { //cannot get rid of this
console.log("hi4");
}, 0);
how do I make it output in order?
If you need to wait for setTimeout in your test() to execute before continuing, the easiest way is to use callback:
function test(callback) {
console.log("hi2");
setTimeout(function () {
console.log("hi3");
// Execute additional logics
callback();
}, 2000);
}
console.log("hi1");
test(function () {
setTimeout(function () {
console.log("hi4");
}, 0);
});
Use the callback or try to show your complicated code is more. We can help you to analyze it.
As others have pointed out setTimeout is asynchronous so they run in the background while the rest of the code continues. I'd guess that at the moment you get something like:
hi1
hi2
hi4
then a 2000ms delay, then
hi3
If you can't change the code much then try changing the delay for hi4 to 4000 like:
setTimeout(function () { //cannot get rid of this
console.log("hi4");
}, 4000);
That should fix the order, but it's still pretty messy and unreliable. I'd rather have something like:
function showMessage(msg, delay) {
setTimeout(function() {
console.log(msg);
}, delay);
}
showMessage('hi1', 0);
showMessage('hi2', 2000);
showMessage('hi3', 4000);
showMessage('hi4', 6000);

using setTimeout synchronously in JavaScript

I have the following scenario:
setTimeout("alert('this alert is timedout and should be the first');", 5000);
alert("this should be the second one");
I need the code after the setTimeout to be executed after the code in the setTimeout is executed. Since the code that comes after the setTimeout is not code of my own I can't put it in the function called in the setTimeout...
Is there any way around this?
Is the code contained in a function?
function test() {
setTimeout(...);
// code that you cannot modify?
}
In that case, you could prevent the function from further execution, and then run it again:
function test(flag) {
if(!flag) {
setTimeout(function() {
alert();
test(true);
}, 5000);
return;
}
// code that you cannot modify
}
I came in a situation where I needed a similar functionality last week and it made me think of this post. Basically I think the "Busy Waiting" to which #AndreKR refers, would be a suitable solution in a lot of situations. Below is the code I used to hog up the browser and force a wait condition.
function pause(milliseconds) {
var dt = new Date();
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
}
document.write("first statement");
alert("first statement");
pause(3000);
document.write("<br />3 seconds");
alert("paused for 3 seconds");
Keep in mind that this code acutally holds up your browser.
Hope it helps anyone.
Using ES6 & promises & async you can achieve running things synchronously.
So what is the code doing?
1. Calls setTimeOut 1st inside of demo then put it into the webApi Stack
2. Creates a promise from the sleep function using the setTimeout, then resolves after the timeout has been completed;
3. By then, the first setTimeout will reach its timer and execute from webApi stack.
4. Then following, the remaining alert will show up.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
setTimeout("alert('this alert is timedout and should be the first');", 5000);
await sleep(5000);
alert('this should be the second one');
}
demo();
Just put it inside the callback:
setTimeout(function() {
alert('this alert is timedout and should be the first');
alert('this should be the second one');
}, 5000);
No, as there is no delay function in Javascript, there is no way to do this other than busy waiting (which would lock up the browser).
ES6 (busy waiting)
const delay = (ms) => {
const startPoint = new Date().getTime()
while (new Date().getTime() - startPoint <= ms) {/* wait */}
}
usage:
delay(1000)
You can create a promise and await for its fulfillment
const timeOut = (secs) => new Promise((res) => setTimeout(res, secs * 1000));
await timeOut(1000)
Here's a good way to make synchronous delay in your code:
async function yourFunction() {
//your code
await delay(n);
//your code
}
function delay(n) {
n = n || 2000;
return new Promise(done => {
setTimeout(() => {
done();
}, n);
});
}
Found it here Right way of delaying execution synchronously in JavaScript without using Loops or Timeouts!
setTimeout(function() {
yourCode(); // alert('this alert is timedout and should be the first');
otherCode(); // alert("this should be the second one");
}, 5000);
I think you have to make a promise and then use a .then() so that you can chain your code together. you should look at this article https://developers.google.com/web/fundamentals/primers/promises
You could attempt to replace window.setTimeout with your own function, like so
window.setTimeout = function(func, timeout) {
func();
}
Which may or may not work properly at all. Besides this, your only option would be to change the original code (which you said you couldn't do)
Bear in mind, changing native functions like this is not exactly a very optimal approach.

Categories