Reputation: 763
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
Upvotes: 18
Views: 71116
Reputation: 127
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()
}
);
Upvotes: 0
Reputation: 7329
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");
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.
Upvotes: 18
Reputation: 8488
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();
Upvotes: 20
Reputation: 1785
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();
Upvotes: 0
Reputation: 1
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/
Upvotes: 4
Reputation: 5444
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();
Upvotes: 0
Reputation: 36511
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>');
}
Upvotes: 1
Reputation: 23660
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();
});
Upvotes: 1