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
-
did you try writing the code at the end in the timeout function itself?Sourabh Kumar Sharma– Sourabh Kumar Sharma2015年05月21日 04:54:17 +00:00Commented May 21, 2015 at 4:54
-
those setTimeout are asynchronous so we doesnt know which one would be executed firstShikha thakur– Shikha thakur2018年02月19日 12:36:07 +00:00Commented Feb 19, 2018 at 12:36
8 Answers 8
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();
Comments
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.
Comments
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/
Comments
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();
});
Comments
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>');
}
Comments
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();
Comments
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();
Comments
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()
}
);