Proper way to wait for one function to finish before continuing? Proper way to wait for one function to finish before continuing? jquery jquery

Proper way to wait for one function to finish before continuing?


One way to deal with asynchronous work like this is to use a callback function, eg:

function firstFunction(_callback){    // do some asynchronous work    // and when the asynchronous stuff is complete    _callback();    }function secondFunction(){    // call first function and pass in a callback function which    // first function runs when it has completed    firstFunction(function() {        console.log('huzzah, I\'m done!');    });    }

As per @Janaka Pushpakumara's suggestion, you can now use arrow functions to achieve the same thing. For example:

firstFunction(() => console.log('huzzah, I\'m done!'))


Update: I answered this quite some time ago, and really want to update it. While callbacks are absolutely fine, in my experience they tend to result in code that is more difficult to read and maintain. There are situations where I still use them though, such as to pass in progress events and the like as parameters. This update is just to emphasise alternatives.

Also the original question doesn't specificallty mention async, so in case anyone is confused, if your function is synchronous, it will block when called. For example:

doSomething()// the function below will wait until doSomething completes if it is synchronousdoSomethingElse()

If though as implied the function is asynchronous, the way I tend to deal with all my asynchronous work today is with async/await. For example:

const secondFunction = async () => {  const result = await firstFunction()  // do something else here after firstFunction completes}

IMO, async/await makes your code much more readable than using promises directly (most of the time). If you need to handle catching errors then use it with try/catch. Read about it more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function .


Use async/await :

async function firstFunction(){  for(i=0;i<x;i++){    // do something  }  return;};

then use await in your other function to wait for it to return:

async function secondFunction(){  await firstFunction();  // now wait for firstFunction to finish...  // do something else};


It appears you're missing an important point here: JavaScript is a single-threaded execution environment. Let's look again at your code, note I've added alert("Here"):

var isPaused = false;function firstFunction(){    isPaused = true;    for(i=0;i<x;i++){        // do something    }    isPaused = false;};function secondFunction(){    firstFunction()    alert("Here");    function waitForIt(){        if (isPaused) {            setTimeout(function(){waitForIt()},100);        } else {            // go do that thing        };    }};

You don't have to wait for isPaused. When you see the "Here" alert, isPaused will be false already, and firstFunction will have returned. That's because you cannot "yield" from inside the for loop (// do something), the loop may not be interrupted and will have to fully complete first (more details: Javascript thread-handling and race-conditions).

That said, you still can make the code flow inside firstFunction to be asynchronous and use either callback or promise to notify the caller. You'd have to give up upon for loop and simulate it with if instead (JSFiddle):

function firstFunction(){    var deferred = $.Deferred();    var i = 0;    var nextStep = function() {        if (i<10) {            // Do something            printOutput("Step: " + i);            i++;            setTimeout(nextStep, 500);         }        else {            deferred.resolve(i);        }    }    nextStep();    return deferred.promise();}function secondFunction(){    var promise = firstFunction();    promise.then(function(result) {         printOutput("Result: " + result);    });}

On a side note, JavaScript 1.7 has introduced yield keyword as a part of generators. That will allow to "punch" asynchronous holes in otherwise synchronous JavaScript code flow (more details and an example). However, the browser support for generators is currently limited to Firefox and Chrome, AFAIK.