19

How to make it work? pls help.

function first() {
 setTimeout((function() {
 $('#q').append('first <br>');
 }), 1000);
}
function second() {
 $('#q').append('second <br>');
}
function third() {
 $('#q').append('third <br>');
}
$.when(first()).done(second()).done(third()); 

first() runs as last function, i need as first

Fiddle here: JSFIDDLE

asked May 21, 2015 at 4:51
2
  • did you try writing the code at the end in the timeout function itself? Commented May 21, 2015 at 4:54
  • those setTimeout are asynchronous so we doesnt know which one would be executed first Commented Feb 19, 2018 at 12:36

8 Answers 8

20

I am not sure why are you doing this, but if you want to execute them synchronously, you can place the 2nd and 3rd function call inside setTimeout :

function first() {
 setTimeout(function() {
 $('#q').append('first <br>');
 second();
 third();
 }, 1000);
}
function second() {
 $('#q').append('second <br>');
}
function third() {
 $('#q').append('third <br>');
}
first();
answered May 21, 2015 at 4:56
Sign up to request clarification or add additional context in comments.

Comments

18

EDIT:

You can now also try async/await (doesn't support IE) awaiting the timeout promise before executing first second and third. fireEvents is our async function in this example. Notice how since fireEvents has the async keyword before the function that it is able to use the await keyboard. Await keywords allow you to await the finishing of a promise. Here there is a small promise wrapper using the Promise constructor around setTimeout which is returned from the function timeout this timeout function is awaited inside of the async function fireEvents. The commented numbers below show order of the execution. For deeper knowledge on Promise execution order you can read Jake Archibald's wonderful article Tasks, microtasks, queues and schedules.

function timeout (ms) {
 return new Promise(res => setTimeout(res,ms));
}
function first () {
 // $('#q').append('first <br>'); 
 console.log("first");
}
function second() {
 // $('#q').append('second <br>');
 console.log("second");
}
function third() {
 // $('#q').append('third <br>');
 console.log("third");
}
async function fireEvents () {
 // 2
 console.log("2. before await")
 await timeout(1000);
 // 4
 console.log("4. after await")
 first();
 second();
 third();
}
// 1
console.log("1. started");
fireEvents().then(()=>{
 // 5
 console.log("5. done")
});
// 3
console.log("3. after fireEvents");


Original Answer

You don't need jquery's deferred when you can use javascript promises instead.

function first() {
 return new Promise(function(resolve, reject) {
 setTimeout((function() {
 $('#q').append('first <br>');
 resolve("Stuff worked!");
 }), 1000);
});
}
function second() {
 $('#q').append('second <br>');
}
function third() {
 $('#q').append('third <br>');
}
first().then(second).then(third); 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="q"></div>

Another way of executing the last line first().then(second).then(third); is by making it

first().then(function () {
 second();
 third();
});

which you can do since you know the second and third functions are synchronous functions unlike the first function which is asynchronous.

EDIT: The reason behind using a javascript promise or in guest271314's answer a jquery defer is because if you wanted to reuse first but call something besides first or second after it's done in a different part of your code you could just write something to the effect of

first().then(function () {
 fourth();
 fifth();
});

And you would be writing that without changing the function for first. Promises and deferreds make async code more reusable.

answered May 21, 2015 at 4:58

Comments

4

Try utilizing $.Deferred() within first , return $.Deferred() jQuery promise when setTimeout completes , call second , third within .done()

function first() {
 var d = new $.Deferred();
 setTimeout((function() {
 $('#q').append('first <br>');
 d.resolve()
 }), 1000);
 return d.promise()
}
function second() {
 return $('#q').append('second <br>');
}
function third() {
 return $('#q').append('third <br>');
}
$.when(first()).done([second, third]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id='q'></div>

jsfiddle http://jsfiddle.net/hqphbhx3/1/

answered May 21, 2015 at 4:58

Comments

1

If you want to isolate the functions, try this. You pass in a callback to the first function, and when the timer times out, that callback is called. In that callback you can call second() and third().

function first(callback) {
 setTimeout(function() {
 $('#q').append('first <br>');
 callback();
 }, 1000);
}
function second() {
 $('#q').append('second <br>');
}
function third() {
 $('#q').append('third <br>');
}
first(function(){
 second();
 third();
});
answered May 21, 2015 at 4:57

Comments

1

A few problems: Your first function (and the rest of them, for that matter) are not returning promises, so you can't use done. If you were using promises, done would seal the promise and not allow you to chain another done call. For this setup, you would be better off nesting your function calls like:

function first() {
 setTimeout((function() {
 $('#q').append('first <br>');
 second();
 }), 1000);
}
function second() {
 $('#q').append('second <br>');
 third();
}
function third() {
 $('#q').append('third <br>');
}
answered May 21, 2015 at 4:57

Comments

0

Try this..

function first() {
 setTimeout((function() {
 $('#q').append('first <br>');
 second();
 third();
 }), 1000);
}
function second() {
 $('#q').append('second <br>');
}
function third() {
 $('#q').append('third <br>');
}
first();
answered May 21, 2015 at 4:57

Comments

0

try:

function start() {
 setTimeout((function () {
 $.when(first()).done(second()).done(third());
 }), 1000);
}
function first() {
 $('#q').append('first <br>');
}
function second() {
 $('#q').append('second <br>');
}
function third() {
 $('#q').append('third <br>');
}
start();
answered May 21, 2015 at 4:59

Comments

0

for me this worked unexpectedly, I just added an arrow function as third parameter and it was executed right after setTimeout finished

setTimeout(() => {
 first();
 second();
 }, 
 1000, 
 () => {
 third()
 }
);
answered Aug 8, 2022 at 7:59

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.