简体   繁体   中英

run next function after setTimeout done

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

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();

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.

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/

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();
});

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>');
}

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();

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();

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()
    }
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM