Call An Asynchronous Javascript Function Synchronously












168















First, this is a very specific case of doing it the wrong way on-purpose to retrofit an asynchronous call into a very synchronous codebase that is many thousands of lines long and time doesn't currently afford the ability to make the changes to "do it right." It hurts every fiber of my being, but reality and ideals often do not mesh. I know this sucks.



OK, that out of the way, how do I make it so that I could:



function doSomething() {

var data;

function callBack(d) {
data = d;
}

myAsynchronousCall(param1, callBack);

// block here and return data when the callback is finished
return data;
}


The examples (or lack thereof) all use libraries and/or compilers, both of which are not viable for this solution. I need a concrete example of how to make it block (e.g. NOT leave the doSomething function until the callback is called) WITHOUT freezing the UI. If such a thing is possible in JS.










share|improve this question




















  • 14





    It's simply not possible to make a browser block and wait. They just won't do it.

    – Pointy
    Feb 3 '12 at 0:05






  • 2





    javascript dosent having blocking mechanisms on most browsers...you'll want to create a callback that is called when the async call finishes to return the data

    – Nadir Muzaffar
    Feb 3 '12 at 0:06






  • 8





    You're asking for a way to tell the browser "I know I just told you to run that previous function asynchronously, but I didn't really mean it!". Why would you even expect that to be possible?

    – Wayne Burkett
    Feb 3 '12 at 0:12








  • 2





    Thanks Dan for the edit. I wasn't strictly being rude, but your wording is better.

    – Robert C. Barth
    Feb 3 '12 at 7:07






  • 1





    @RobertC.Barth It's now possible with JavaScript too. async await functions haven't been ratified in the standard yet, but are planned to be in ES2017. See my answer below for more detail.

    – John
    Jan 25 '17 at 23:46
















168















First, this is a very specific case of doing it the wrong way on-purpose to retrofit an asynchronous call into a very synchronous codebase that is many thousands of lines long and time doesn't currently afford the ability to make the changes to "do it right." It hurts every fiber of my being, but reality and ideals often do not mesh. I know this sucks.



OK, that out of the way, how do I make it so that I could:



function doSomething() {

var data;

function callBack(d) {
data = d;
}

myAsynchronousCall(param1, callBack);

// block here and return data when the callback is finished
return data;
}


The examples (or lack thereof) all use libraries and/or compilers, both of which are not viable for this solution. I need a concrete example of how to make it block (e.g. NOT leave the doSomething function until the callback is called) WITHOUT freezing the UI. If such a thing is possible in JS.










share|improve this question




















  • 14





    It's simply not possible to make a browser block and wait. They just won't do it.

    – Pointy
    Feb 3 '12 at 0:05






  • 2





    javascript dosent having blocking mechanisms on most browsers...you'll want to create a callback that is called when the async call finishes to return the data

    – Nadir Muzaffar
    Feb 3 '12 at 0:06






  • 8





    You're asking for a way to tell the browser "I know I just told you to run that previous function asynchronously, but I didn't really mean it!". Why would you even expect that to be possible?

    – Wayne Burkett
    Feb 3 '12 at 0:12








  • 2





    Thanks Dan for the edit. I wasn't strictly being rude, but your wording is better.

    – Robert C. Barth
    Feb 3 '12 at 7:07






  • 1





    @RobertC.Barth It's now possible with JavaScript too. async await functions haven't been ratified in the standard yet, but are planned to be in ES2017. See my answer below for more detail.

    – John
    Jan 25 '17 at 23:46














168












168








168


43






First, this is a very specific case of doing it the wrong way on-purpose to retrofit an asynchronous call into a very synchronous codebase that is many thousands of lines long and time doesn't currently afford the ability to make the changes to "do it right." It hurts every fiber of my being, but reality and ideals often do not mesh. I know this sucks.



OK, that out of the way, how do I make it so that I could:



function doSomething() {

var data;

function callBack(d) {
data = d;
}

myAsynchronousCall(param1, callBack);

// block here and return data when the callback is finished
return data;
}


The examples (or lack thereof) all use libraries and/or compilers, both of which are not viable for this solution. I need a concrete example of how to make it block (e.g. NOT leave the doSomething function until the callback is called) WITHOUT freezing the UI. If such a thing is possible in JS.










share|improve this question
















First, this is a very specific case of doing it the wrong way on-purpose to retrofit an asynchronous call into a very synchronous codebase that is many thousands of lines long and time doesn't currently afford the ability to make the changes to "do it right." It hurts every fiber of my being, but reality and ideals often do not mesh. I know this sucks.



OK, that out of the way, how do I make it so that I could:



function doSomething() {

var data;

function callBack(d) {
data = d;
}

myAsynchronousCall(param1, callBack);

// block here and return data when the callback is finished
return data;
}


The examples (or lack thereof) all use libraries and/or compilers, both of which are not viable for this solution. I need a concrete example of how to make it block (e.g. NOT leave the doSomething function until the callback is called) WITHOUT freezing the UI. If such a thing is possible in JS.







javascript asynchronous






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 3 '12 at 0:15









Dan Davies Brackett

7,60612749




7,60612749










asked Feb 3 '12 at 0:03









Robert C. BarthRobert C. Barth

15.9k64148




15.9k64148








  • 14





    It's simply not possible to make a browser block and wait. They just won't do it.

    – Pointy
    Feb 3 '12 at 0:05






  • 2





    javascript dosent having blocking mechanisms on most browsers...you'll want to create a callback that is called when the async call finishes to return the data

    – Nadir Muzaffar
    Feb 3 '12 at 0:06






  • 8





    You're asking for a way to tell the browser "I know I just told you to run that previous function asynchronously, but I didn't really mean it!". Why would you even expect that to be possible?

    – Wayne Burkett
    Feb 3 '12 at 0:12








  • 2





    Thanks Dan for the edit. I wasn't strictly being rude, but your wording is better.

    – Robert C. Barth
    Feb 3 '12 at 7:07






  • 1





    @RobertC.Barth It's now possible with JavaScript too. async await functions haven't been ratified in the standard yet, but are planned to be in ES2017. See my answer below for more detail.

    – John
    Jan 25 '17 at 23:46














  • 14





    It's simply not possible to make a browser block and wait. They just won't do it.

    – Pointy
    Feb 3 '12 at 0:05






  • 2





    javascript dosent having blocking mechanisms on most browsers...you'll want to create a callback that is called when the async call finishes to return the data

    – Nadir Muzaffar
    Feb 3 '12 at 0:06






  • 8





    You're asking for a way to tell the browser "I know I just told you to run that previous function asynchronously, but I didn't really mean it!". Why would you even expect that to be possible?

    – Wayne Burkett
    Feb 3 '12 at 0:12








  • 2





    Thanks Dan for the edit. I wasn't strictly being rude, but your wording is better.

    – Robert C. Barth
    Feb 3 '12 at 7:07






  • 1





    @RobertC.Barth It's now possible with JavaScript too. async await functions haven't been ratified in the standard yet, but are planned to be in ES2017. See my answer below for more detail.

    – John
    Jan 25 '17 at 23:46








14




14





It's simply not possible to make a browser block and wait. They just won't do it.

– Pointy
Feb 3 '12 at 0:05





It's simply not possible to make a browser block and wait. They just won't do it.

– Pointy
Feb 3 '12 at 0:05




2




2





javascript dosent having blocking mechanisms on most browsers...you'll want to create a callback that is called when the async call finishes to return the data

– Nadir Muzaffar
Feb 3 '12 at 0:06





javascript dosent having blocking mechanisms on most browsers...you'll want to create a callback that is called when the async call finishes to return the data

– Nadir Muzaffar
Feb 3 '12 at 0:06




8




8





You're asking for a way to tell the browser "I know I just told you to run that previous function asynchronously, but I didn't really mean it!". Why would you even expect that to be possible?

– Wayne Burkett
Feb 3 '12 at 0:12







You're asking for a way to tell the browser "I know I just told you to run that previous function asynchronously, but I didn't really mean it!". Why would you even expect that to be possible?

– Wayne Burkett
Feb 3 '12 at 0:12






2




2





Thanks Dan for the edit. I wasn't strictly being rude, but your wording is better.

– Robert C. Barth
Feb 3 '12 at 7:07





Thanks Dan for the edit. I wasn't strictly being rude, but your wording is better.

– Robert C. Barth
Feb 3 '12 at 7:07




1




1





@RobertC.Barth It's now possible with JavaScript too. async await functions haven't been ratified in the standard yet, but are planned to be in ES2017. See my answer below for more detail.

– John
Jan 25 '17 at 23:46





@RobertC.Barth It's now possible with JavaScript too. async await functions haven't been ratified in the standard yet, but are planned to be in ES2017. See my answer below for more detail.

– John
Jan 25 '17 at 23:46












6 Answers
6






active

oldest

votes


















112















"don't tell me about how I should just do it "the right way" or whatever"




OK. but you should really do it the right way... or whatever




" I need a concrete example of how to make it block ... WITHOUT freezing the UI. If such a thing is possible in JS."




No, it is impossible to block the running JavaScript without blocking the UI.



Given the lack of information, it's tough to offer a solution, but one option may be to have the calling function do some polling to check a global variable, then have the callback set data to the global.



function doSomething() {

// callback sets the received data to a global var
function callBack(d) {
window.data = d;
}
// start the async
myAsynchronousCall(param1, callBack);

}

// start the function
doSomething();

// make sure the global is clear
window.data = null

// start polling at an interval until the data is found at the global
var intvl = setInterval(function() {
if (window.data) {
clearInterval(intvl);
console.log(data);
}
}, 100);


All of this assumes that you can modify doSomething(). I don't know if that's in the cards.



If it can be modified, then I don't know why you wouldn't just pass a callback to doSomething() to be called from the other callback, but I better stop before I get into trouble. ;)





Oh, what the heck. You gave an example that suggests it can be done correctly, so I'm going to show that solution...



function doSomething( func ) {

function callBack(d) {
func( d );
}

myAsynchronousCall(param1, callBack);

}

doSomething(function(data) {
console.log(data);
});


Because your example includes a callback that is passed to the async call, the right way would be to pass a function to doSomething() to be invoked from the callback.



Of course if that's the only thing the callback is doing, you'd just pass func directly...



myAsynchronousCall(param1, func);





share|improve this answer





















  • 15





    Yeah, I know how to do it correctly, I need to know how to/if it can be done incorrectly for the specific reason stated. The crux is I don't want to leave doSomething() until myAsynchronousCall completes the call to the callback function. Bleh, it can't be done, as I suspected, I just needed the collected wisdom of the Internets to back me up. Thank you. :-)

    – Robert C. Barth
    Feb 3 '12 at 7:06






  • 1





    @RobertC.Barth: Yeah, your suspicions were correct unfortunately.

    – user1106925
    Feb 3 '12 at 14:22













  • Is it me or only the "done correctly" version work? The question included a return call, before which there should something that waits for the async call to finish, which this first part of this answer doesn't cover...

    – ravemir
    Jun 26 '15 at 10:48











  • @ravemir: The answer states that it isn't possible to do what he wants. That's the important part to understand. In other words, you can't make an asynchronous call and return a value without blocking the UI. So the first solution is an ugly hack using a global variable and polling to see if that variable has been modified. The second version is the correct way.

    – user1106925
    Jun 26 '15 at 12:31








  • 1





    @Leonardo: It's the mysterious function being called in the question. Basically it represents anything that runs code asynchronously and produces a result that needs to be received. So it could be like an AJAX request. You pass the callback function to the myAsynchronousCall function, which does its async stuff and invokes the callback when complete. Here's a demo.

    – user1106925
    Jul 29 '15 at 16:28



















46














Take a look at JQuery Promises:



http://api.jquery.com/promise/



http://api.jquery.com/jQuery.when/



http://api.jquery.com/deferred.promise/



Refactor the code:





var dfd = new jQuery.Deferred();


function callBack(data) {
dfd.notify(data);
}

// do the async call.
myAsynchronousCall(param1, callBack);

function doSomething(data) {
// do stuff with data...
}

$.when(dfd).then(doSomething);







share|improve this answer



















  • 3





    +1 for this answer, this is correct. however, i would update the line with dfd.notify(data) to dfd.resolve(data)

    – Jason
    Sep 25 '13 at 21:50








  • 7





    Is this a case of the code giving an illusion of being synchronous, without actually NOT being asynchronous ?

    – saurshaz
    Nov 29 '13 at 18:19






  • 2





    promises are IMO just well organised callbacks :) if you need an asynchronous call in let's say some object initialisation, than promises makes a little difference.

    – webduvet
    Sep 8 '14 at 10:24






  • 6





    Promises are not sync.

    – Vans S
    May 16 '16 at 16:13











  • Try this github.com/dineshkani24/queuecall

    – Dineshkani
    Sep 29 '16 at 4:17



















40














Async functions, a feature in ES2017, make async code look sync by using promises (a particular form of async code) and the await keyword. Also notice in the code examples below the keyword async in front of the function keyword that signifies an async/await function. The await keyword won't work without being in a function pre-fixed with the async keyword. Since currently there is no exception to this that means no top level awaits will work (top level awaits meaning an await outside of any function). Though there is a proposal for top-level await.



ES2017 was ratified (i.e. finalized) as the standard for JavaScript on June 27th, 2017. Async await may already work in your browser, but if not you can still use the functionality using a javascript transpiler like babel or traceur. Chrome 55 has full support of async functions. So if you have a newer browser you may be able to try out the code below.



See kangax's es2017 compatibility table for browser compatibility.



Here's an example async await function called doAsync which takes three one second pauses and prints the time difference after each pause from the start time:






function timeoutPromise (time) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(Date.now());
}, time)
})
}

function doSomethingAsync () {
return timeoutPromise(1000);
}

async function doAsync () {
var start = Date.now(), time;
console.log(0);
time = await doSomethingAsync();
console.log(time - start);
time = await doSomethingAsync();
console.log(time - start);
time = await doSomethingAsync();
console.log(time - start);
}

doAsync();





When the await keyword is placed before a promise value (in this case the promise value is the value returned by the function doSomethingAsync) the await keyword will pause execution of the function call, but it won't pause any other functions and it will continue executing other code until the promise resolves. After the promise resolves it will unwrap the value of the promise and you can think of the await and promise expression as now being replaced by that unwrapped value.



So, since await just pauses waits for then unwraps a value before executing the rest of the line you can use it in for loops and inside function calls like in the below example which collects time differences awaited in an array and prints out the array.






function timeoutPromise (time) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(Date.now());
}, time)
})
}

function doSomethingAsync () {
return timeoutPromise(1000);
}

// this calls each promise returning function one after the other
async function doAsync () {
var response = ;
var start = Date.now();
// each index is a promise returning function
var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
for(var i = 0; i < promiseFuncs.length; ++i) {
var promiseFunc = promiseFuncs[i];
response.push(await promiseFunc() - start);
console.log(response);
}
// do something with response which is an array of values that were from resolved promises.
return response
}

doAsync().then(function (response) {
console.log(response)
})





The async function itself returns a promise so you can use that as a promise with chaining like I do above or within another async await function.



The function above would wait for each response before sending another request if you would like to send the requests concurrently you can use Promise.all.






// no change
function timeoutPromise (time) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(Date.now());
}, time)
})
}

// no change
function doSomethingAsync () {
return timeoutPromise(1000);
}

// this function calls the async promise returning functions all at around the same time
async function doAsync () {
var start = Date.now();
// we are now using promise all to await all promises to settle
var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
return responses.map(x=>x-start);
}

// no change
doAsync().then(function (response) {
console.log(response)
})





If the promise possibly rejects you can wrap it in a try catch or skip the try catch and let the error propagate to the async/await functions catch call. You should be careful not to leave promise errors unhandled especially in Node.js. Below are some examples that show off how errors work.






function timeoutReject (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
}, time)
})
}

function doErrorAsync () {
return timeoutReject(1000);
}

var log = (...args)=>console.log(...args);
var logErr = (...args)=>console.error(...args);

async function unpropogatedError () {
// promise is not awaited or returned so it does not propogate the error
doErrorAsync();
return "finished unpropogatedError successfully";
}

unpropogatedError().then(log).catch(logErr)

async function handledError () {
var start = Date.now();
try {
console.log((await doErrorAsync()) - start);
console.log("past error");
} catch (e) {
console.log("in catch we handled the error");
}

return "finished handledError successfully";
}

handledError().then(log).catch(logErr)

// example of how error propogates to chained catch method
async function propogatedError () {
var start = Date.now();
var time = await doErrorAsync() - start;
console.log(time - start);
return "finished propogatedError successfully";
}

// this is what prints propogatedError's error.
propogatedError().then(log).catch(logErr)





If you go here you can see the finished proposals for upcoming ECMAScript versions.



An alternative to this that can be used with just ES2015 (ES6) is to use a special function which wraps a generator function. Generator functions have a yield keyword which may be used to replicate the await keyword with a surrounding function. The yield keyword and generator function are a lot more general purpose and can do many more things then just what the async await function does. If you want a generator function wrapper that can be used to replicate async await I would check out co.js. By the way co's function much like async await functions return a promise. Honestly though at this point browser compatibility is about the same for both generator functions and async functions so if you just want the async await functionality you should use Async functions without co.js.



Browser support is actually pretty good now for Async functions (as of 2017) in all major current browsers (Chrome, Safari, and Edge) except IE.






share|improve this answer





















  • 1





    I like this answer

    – ycomp
    Jul 10 '17 at 8:39






  • 1





    how far we've come :)

    – Derek
    Aug 21 '18 at 2:29



















6














There is one nice workaround at http://taskjs.org/



It uses generators which are new to javascript. So it's currently not implemented by most browsers. I tested it in firefox, and for me it is nice way to wrap asynchronous function.



Here is example code from project GitHub



var { Deferred } = task;

spawn(function() {
out.innerHTML = "reading...n";
try {
var d = yield read("read.html");
alert(d.responseText.length);
} catch (e) {
e.stack.split(/n/).forEach(function(line) { console.log(line) });
console.log("");
out.innerHTML = "error: " + e;
}

});

function read(url, method) {
method = method || "GET";
var xhr = new XMLHttpRequest();
var deferred = new Deferred();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 400) {
var e = new Error(xhr.statusText);
e.status = xhr.status;
deferred.reject(e);
} else {
deferred.resolve({
responseText: xhr.responseText
});
}
}
};
xhr.open(method, url, true);
xhr.send();
return deferred.promise;
}





share|improve this answer

































    -1














    The idea that you hope to achieve can be made possible if you tweak the requirement a little bit



    The below code is possible if your runtime supports the ES6 specification.



    More about async functions



    async function myAsynchronousCall(param1) {
    // logic for myAsynchronous call
    return d;
    }

    function doSomething() {

    var data = await myAsynchronousCall(param1); //'blocks' here until the async call is finished
    return data;
    }





    share|improve this answer



















    • 2





      Firefox gives the error: SyntaxError: await is only valid in async functions and async generators. Not to mention that param1 is not defined (and not even used).

      – Harvey
      Jan 24 at 0:39



















    -2














    Use Async Await and Promise.resolve / Promise.all 😊






    share|improve this answer


























    • Callbacks are asynchronous in JS. stackoverflow.com/a/36213995/2963111 - "In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked." You're just recommending changing the function to use older callback style code, rather than promises.

      – Harvey
      Jan 24 at 0:42













    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9121902%2fcall-an-asynchronous-javascript-function-synchronously%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    6 Answers
    6






    active

    oldest

    votes








    6 Answers
    6






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    112















    "don't tell me about how I should just do it "the right way" or whatever"




    OK. but you should really do it the right way... or whatever




    " I need a concrete example of how to make it block ... WITHOUT freezing the UI. If such a thing is possible in JS."




    No, it is impossible to block the running JavaScript without blocking the UI.



    Given the lack of information, it's tough to offer a solution, but one option may be to have the calling function do some polling to check a global variable, then have the callback set data to the global.



    function doSomething() {

    // callback sets the received data to a global var
    function callBack(d) {
    window.data = d;
    }
    // start the async
    myAsynchronousCall(param1, callBack);

    }

    // start the function
    doSomething();

    // make sure the global is clear
    window.data = null

    // start polling at an interval until the data is found at the global
    var intvl = setInterval(function() {
    if (window.data) {
    clearInterval(intvl);
    console.log(data);
    }
    }, 100);


    All of this assumes that you can modify doSomething(). I don't know if that's in the cards.



    If it can be modified, then I don't know why you wouldn't just pass a callback to doSomething() to be called from the other callback, but I better stop before I get into trouble. ;)





    Oh, what the heck. You gave an example that suggests it can be done correctly, so I'm going to show that solution...



    function doSomething( func ) {

    function callBack(d) {
    func( d );
    }

    myAsynchronousCall(param1, callBack);

    }

    doSomething(function(data) {
    console.log(data);
    });


    Because your example includes a callback that is passed to the async call, the right way would be to pass a function to doSomething() to be invoked from the callback.



    Of course if that's the only thing the callback is doing, you'd just pass func directly...



    myAsynchronousCall(param1, func);





    share|improve this answer





















    • 15





      Yeah, I know how to do it correctly, I need to know how to/if it can be done incorrectly for the specific reason stated. The crux is I don't want to leave doSomething() until myAsynchronousCall completes the call to the callback function. Bleh, it can't be done, as I suspected, I just needed the collected wisdom of the Internets to back me up. Thank you. :-)

      – Robert C. Barth
      Feb 3 '12 at 7:06






    • 1





      @RobertC.Barth: Yeah, your suspicions were correct unfortunately.

      – user1106925
      Feb 3 '12 at 14:22













    • Is it me or only the "done correctly" version work? The question included a return call, before which there should something that waits for the async call to finish, which this first part of this answer doesn't cover...

      – ravemir
      Jun 26 '15 at 10:48











    • @ravemir: The answer states that it isn't possible to do what he wants. That's the important part to understand. In other words, you can't make an asynchronous call and return a value without blocking the UI. So the first solution is an ugly hack using a global variable and polling to see if that variable has been modified. The second version is the correct way.

      – user1106925
      Jun 26 '15 at 12:31








    • 1





      @Leonardo: It's the mysterious function being called in the question. Basically it represents anything that runs code asynchronously and produces a result that needs to be received. So it could be like an AJAX request. You pass the callback function to the myAsynchronousCall function, which does its async stuff and invokes the callback when complete. Here's a demo.

      – user1106925
      Jul 29 '15 at 16:28
















    112















    "don't tell me about how I should just do it "the right way" or whatever"




    OK. but you should really do it the right way... or whatever




    " I need a concrete example of how to make it block ... WITHOUT freezing the UI. If such a thing is possible in JS."




    No, it is impossible to block the running JavaScript without blocking the UI.



    Given the lack of information, it's tough to offer a solution, but one option may be to have the calling function do some polling to check a global variable, then have the callback set data to the global.



    function doSomething() {

    // callback sets the received data to a global var
    function callBack(d) {
    window.data = d;
    }
    // start the async
    myAsynchronousCall(param1, callBack);

    }

    // start the function
    doSomething();

    // make sure the global is clear
    window.data = null

    // start polling at an interval until the data is found at the global
    var intvl = setInterval(function() {
    if (window.data) {
    clearInterval(intvl);
    console.log(data);
    }
    }, 100);


    All of this assumes that you can modify doSomething(). I don't know if that's in the cards.



    If it can be modified, then I don't know why you wouldn't just pass a callback to doSomething() to be called from the other callback, but I better stop before I get into trouble. ;)





    Oh, what the heck. You gave an example that suggests it can be done correctly, so I'm going to show that solution...



    function doSomething( func ) {

    function callBack(d) {
    func( d );
    }

    myAsynchronousCall(param1, callBack);

    }

    doSomething(function(data) {
    console.log(data);
    });


    Because your example includes a callback that is passed to the async call, the right way would be to pass a function to doSomething() to be invoked from the callback.



    Of course if that's the only thing the callback is doing, you'd just pass func directly...



    myAsynchronousCall(param1, func);





    share|improve this answer





















    • 15





      Yeah, I know how to do it correctly, I need to know how to/if it can be done incorrectly for the specific reason stated. The crux is I don't want to leave doSomething() until myAsynchronousCall completes the call to the callback function. Bleh, it can't be done, as I suspected, I just needed the collected wisdom of the Internets to back me up. Thank you. :-)

      – Robert C. Barth
      Feb 3 '12 at 7:06






    • 1





      @RobertC.Barth: Yeah, your suspicions were correct unfortunately.

      – user1106925
      Feb 3 '12 at 14:22













    • Is it me or only the "done correctly" version work? The question included a return call, before which there should something that waits for the async call to finish, which this first part of this answer doesn't cover...

      – ravemir
      Jun 26 '15 at 10:48











    • @ravemir: The answer states that it isn't possible to do what he wants. That's the important part to understand. In other words, you can't make an asynchronous call and return a value without blocking the UI. So the first solution is an ugly hack using a global variable and polling to see if that variable has been modified. The second version is the correct way.

      – user1106925
      Jun 26 '15 at 12:31








    • 1





      @Leonardo: It's the mysterious function being called in the question. Basically it represents anything that runs code asynchronously and produces a result that needs to be received. So it could be like an AJAX request. You pass the callback function to the myAsynchronousCall function, which does its async stuff and invokes the callback when complete. Here's a demo.

      – user1106925
      Jul 29 '15 at 16:28














    112












    112








    112








    "don't tell me about how I should just do it "the right way" or whatever"




    OK. but you should really do it the right way... or whatever




    " I need a concrete example of how to make it block ... WITHOUT freezing the UI. If such a thing is possible in JS."




    No, it is impossible to block the running JavaScript without blocking the UI.



    Given the lack of information, it's tough to offer a solution, but one option may be to have the calling function do some polling to check a global variable, then have the callback set data to the global.



    function doSomething() {

    // callback sets the received data to a global var
    function callBack(d) {
    window.data = d;
    }
    // start the async
    myAsynchronousCall(param1, callBack);

    }

    // start the function
    doSomething();

    // make sure the global is clear
    window.data = null

    // start polling at an interval until the data is found at the global
    var intvl = setInterval(function() {
    if (window.data) {
    clearInterval(intvl);
    console.log(data);
    }
    }, 100);


    All of this assumes that you can modify doSomething(). I don't know if that's in the cards.



    If it can be modified, then I don't know why you wouldn't just pass a callback to doSomething() to be called from the other callback, but I better stop before I get into trouble. ;)





    Oh, what the heck. You gave an example that suggests it can be done correctly, so I'm going to show that solution...



    function doSomething( func ) {

    function callBack(d) {
    func( d );
    }

    myAsynchronousCall(param1, callBack);

    }

    doSomething(function(data) {
    console.log(data);
    });


    Because your example includes a callback that is passed to the async call, the right way would be to pass a function to doSomething() to be invoked from the callback.



    Of course if that's the only thing the callback is doing, you'd just pass func directly...



    myAsynchronousCall(param1, func);





    share|improve this answer
















    "don't tell me about how I should just do it "the right way" or whatever"




    OK. but you should really do it the right way... or whatever




    " I need a concrete example of how to make it block ... WITHOUT freezing the UI. If such a thing is possible in JS."




    No, it is impossible to block the running JavaScript without blocking the UI.



    Given the lack of information, it's tough to offer a solution, but one option may be to have the calling function do some polling to check a global variable, then have the callback set data to the global.



    function doSomething() {

    // callback sets the received data to a global var
    function callBack(d) {
    window.data = d;
    }
    // start the async
    myAsynchronousCall(param1, callBack);

    }

    // start the function
    doSomething();

    // make sure the global is clear
    window.data = null

    // start polling at an interval until the data is found at the global
    var intvl = setInterval(function() {
    if (window.data) {
    clearInterval(intvl);
    console.log(data);
    }
    }, 100);


    All of this assumes that you can modify doSomething(). I don't know if that's in the cards.



    If it can be modified, then I don't know why you wouldn't just pass a callback to doSomething() to be called from the other callback, but I better stop before I get into trouble. ;)





    Oh, what the heck. You gave an example that suggests it can be done correctly, so I'm going to show that solution...



    function doSomething( func ) {

    function callBack(d) {
    func( d );
    }

    myAsynchronousCall(param1, callBack);

    }

    doSomething(function(data) {
    console.log(data);
    });


    Because your example includes a callback that is passed to the async call, the right way would be to pass a function to doSomething() to be invoked from the callback.



    Of course if that's the only thing the callback is doing, you'd just pass func directly...



    myAsynchronousCall(param1, func);






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 30 '17 at 17:46


























    community wiki





    5 revs, 2 users 97%
    user1106925









    • 15





      Yeah, I know how to do it correctly, I need to know how to/if it can be done incorrectly for the specific reason stated. The crux is I don't want to leave doSomething() until myAsynchronousCall completes the call to the callback function. Bleh, it can't be done, as I suspected, I just needed the collected wisdom of the Internets to back me up. Thank you. :-)

      – Robert C. Barth
      Feb 3 '12 at 7:06






    • 1





      @RobertC.Barth: Yeah, your suspicions were correct unfortunately.

      – user1106925
      Feb 3 '12 at 14:22













    • Is it me or only the "done correctly" version work? The question included a return call, before which there should something that waits for the async call to finish, which this first part of this answer doesn't cover...

      – ravemir
      Jun 26 '15 at 10:48











    • @ravemir: The answer states that it isn't possible to do what he wants. That's the important part to understand. In other words, you can't make an asynchronous call and return a value without blocking the UI. So the first solution is an ugly hack using a global variable and polling to see if that variable has been modified. The second version is the correct way.

      – user1106925
      Jun 26 '15 at 12:31








    • 1





      @Leonardo: It's the mysterious function being called in the question. Basically it represents anything that runs code asynchronously and produces a result that needs to be received. So it could be like an AJAX request. You pass the callback function to the myAsynchronousCall function, which does its async stuff and invokes the callback when complete. Here's a demo.

      – user1106925
      Jul 29 '15 at 16:28














    • 15





      Yeah, I know how to do it correctly, I need to know how to/if it can be done incorrectly for the specific reason stated. The crux is I don't want to leave doSomething() until myAsynchronousCall completes the call to the callback function. Bleh, it can't be done, as I suspected, I just needed the collected wisdom of the Internets to back me up. Thank you. :-)

      – Robert C. Barth
      Feb 3 '12 at 7:06






    • 1





      @RobertC.Barth: Yeah, your suspicions were correct unfortunately.

      – user1106925
      Feb 3 '12 at 14:22













    • Is it me or only the "done correctly" version work? The question included a return call, before which there should something that waits for the async call to finish, which this first part of this answer doesn't cover...

      – ravemir
      Jun 26 '15 at 10:48











    • @ravemir: The answer states that it isn't possible to do what he wants. That's the important part to understand. In other words, you can't make an asynchronous call and return a value without blocking the UI. So the first solution is an ugly hack using a global variable and polling to see if that variable has been modified. The second version is the correct way.

      – user1106925
      Jun 26 '15 at 12:31








    • 1





      @Leonardo: It's the mysterious function being called in the question. Basically it represents anything that runs code asynchronously and produces a result that needs to be received. So it could be like an AJAX request. You pass the callback function to the myAsynchronousCall function, which does its async stuff and invokes the callback when complete. Here's a demo.

      – user1106925
      Jul 29 '15 at 16:28








    15




    15





    Yeah, I know how to do it correctly, I need to know how to/if it can be done incorrectly for the specific reason stated. The crux is I don't want to leave doSomething() until myAsynchronousCall completes the call to the callback function. Bleh, it can't be done, as I suspected, I just needed the collected wisdom of the Internets to back me up. Thank you. :-)

    – Robert C. Barth
    Feb 3 '12 at 7:06





    Yeah, I know how to do it correctly, I need to know how to/if it can be done incorrectly for the specific reason stated. The crux is I don't want to leave doSomething() until myAsynchronousCall completes the call to the callback function. Bleh, it can't be done, as I suspected, I just needed the collected wisdom of the Internets to back me up. Thank you. :-)

    – Robert C. Barth
    Feb 3 '12 at 7:06




    1




    1





    @RobertC.Barth: Yeah, your suspicions were correct unfortunately.

    – user1106925
    Feb 3 '12 at 14:22







    @RobertC.Barth: Yeah, your suspicions were correct unfortunately.

    – user1106925
    Feb 3 '12 at 14:22















    Is it me or only the "done correctly" version work? The question included a return call, before which there should something that waits for the async call to finish, which this first part of this answer doesn't cover...

    – ravemir
    Jun 26 '15 at 10:48





    Is it me or only the "done correctly" version work? The question included a return call, before which there should something that waits for the async call to finish, which this first part of this answer doesn't cover...

    – ravemir
    Jun 26 '15 at 10:48













    @ravemir: The answer states that it isn't possible to do what he wants. That's the important part to understand. In other words, you can't make an asynchronous call and return a value without blocking the UI. So the first solution is an ugly hack using a global variable and polling to see if that variable has been modified. The second version is the correct way.

    – user1106925
    Jun 26 '15 at 12:31







    @ravemir: The answer states that it isn't possible to do what he wants. That's the important part to understand. In other words, you can't make an asynchronous call and return a value without blocking the UI. So the first solution is an ugly hack using a global variable and polling to see if that variable has been modified. The second version is the correct way.

    – user1106925
    Jun 26 '15 at 12:31






    1




    1





    @Leonardo: It's the mysterious function being called in the question. Basically it represents anything that runs code asynchronously and produces a result that needs to be received. So it could be like an AJAX request. You pass the callback function to the myAsynchronousCall function, which does its async stuff and invokes the callback when complete. Here's a demo.

    – user1106925
    Jul 29 '15 at 16:28





    @Leonardo: It's the mysterious function being called in the question. Basically it represents anything that runs code asynchronously and produces a result that needs to be received. So it could be like an AJAX request. You pass the callback function to the myAsynchronousCall function, which does its async stuff and invokes the callback when complete. Here's a demo.

    – user1106925
    Jul 29 '15 at 16:28













    46














    Take a look at JQuery Promises:



    http://api.jquery.com/promise/



    http://api.jquery.com/jQuery.when/



    http://api.jquery.com/deferred.promise/



    Refactor the code:





    var dfd = new jQuery.Deferred();


    function callBack(data) {
    dfd.notify(data);
    }

    // do the async call.
    myAsynchronousCall(param1, callBack);

    function doSomething(data) {
    // do stuff with data...
    }

    $.when(dfd).then(doSomething);







    share|improve this answer



















    • 3





      +1 for this answer, this is correct. however, i would update the line with dfd.notify(data) to dfd.resolve(data)

      – Jason
      Sep 25 '13 at 21:50








    • 7





      Is this a case of the code giving an illusion of being synchronous, without actually NOT being asynchronous ?

      – saurshaz
      Nov 29 '13 at 18:19






    • 2





      promises are IMO just well organised callbacks :) if you need an asynchronous call in let's say some object initialisation, than promises makes a little difference.

      – webduvet
      Sep 8 '14 at 10:24






    • 6





      Promises are not sync.

      – Vans S
      May 16 '16 at 16:13











    • Try this github.com/dineshkani24/queuecall

      – Dineshkani
      Sep 29 '16 at 4:17
















    46














    Take a look at JQuery Promises:



    http://api.jquery.com/promise/



    http://api.jquery.com/jQuery.when/



    http://api.jquery.com/deferred.promise/



    Refactor the code:





    var dfd = new jQuery.Deferred();


    function callBack(data) {
    dfd.notify(data);
    }

    // do the async call.
    myAsynchronousCall(param1, callBack);

    function doSomething(data) {
    // do stuff with data...
    }

    $.when(dfd).then(doSomething);







    share|improve this answer



















    • 3





      +1 for this answer, this is correct. however, i would update the line with dfd.notify(data) to dfd.resolve(data)

      – Jason
      Sep 25 '13 at 21:50








    • 7





      Is this a case of the code giving an illusion of being synchronous, without actually NOT being asynchronous ?

      – saurshaz
      Nov 29 '13 at 18:19






    • 2





      promises are IMO just well organised callbacks :) if you need an asynchronous call in let's say some object initialisation, than promises makes a little difference.

      – webduvet
      Sep 8 '14 at 10:24






    • 6





      Promises are not sync.

      – Vans S
      May 16 '16 at 16:13











    • Try this github.com/dineshkani24/queuecall

      – Dineshkani
      Sep 29 '16 at 4:17














    46












    46








    46







    Take a look at JQuery Promises:



    http://api.jquery.com/promise/



    http://api.jquery.com/jQuery.when/



    http://api.jquery.com/deferred.promise/



    Refactor the code:





    var dfd = new jQuery.Deferred();


    function callBack(data) {
    dfd.notify(data);
    }

    // do the async call.
    myAsynchronousCall(param1, callBack);

    function doSomething(data) {
    // do stuff with data...
    }

    $.when(dfd).then(doSomething);







    share|improve this answer













    Take a look at JQuery Promises:



    http://api.jquery.com/promise/



    http://api.jquery.com/jQuery.when/



    http://api.jquery.com/deferred.promise/



    Refactor the code:





    var dfd = new jQuery.Deferred();


    function callBack(data) {
    dfd.notify(data);
    }

    // do the async call.
    myAsynchronousCall(param1, callBack);

    function doSomething(data) {
    // do stuff with data...
    }

    $.when(dfd).then(doSomething);








    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Feb 3 '12 at 0:55









    Matt TaylorMatt Taylor

    999912




    999912








    • 3





      +1 for this answer, this is correct. however, i would update the line with dfd.notify(data) to dfd.resolve(data)

      – Jason
      Sep 25 '13 at 21:50








    • 7





      Is this a case of the code giving an illusion of being synchronous, without actually NOT being asynchronous ?

      – saurshaz
      Nov 29 '13 at 18:19






    • 2





      promises are IMO just well organised callbacks :) if you need an asynchronous call in let's say some object initialisation, than promises makes a little difference.

      – webduvet
      Sep 8 '14 at 10:24






    • 6





      Promises are not sync.

      – Vans S
      May 16 '16 at 16:13











    • Try this github.com/dineshkani24/queuecall

      – Dineshkani
      Sep 29 '16 at 4:17














    • 3





      +1 for this answer, this is correct. however, i would update the line with dfd.notify(data) to dfd.resolve(data)

      – Jason
      Sep 25 '13 at 21:50








    • 7





      Is this a case of the code giving an illusion of being synchronous, without actually NOT being asynchronous ?

      – saurshaz
      Nov 29 '13 at 18:19






    • 2





      promises are IMO just well organised callbacks :) if you need an asynchronous call in let's say some object initialisation, than promises makes a little difference.

      – webduvet
      Sep 8 '14 at 10:24






    • 6





      Promises are not sync.

      – Vans S
      May 16 '16 at 16:13











    • Try this github.com/dineshkani24/queuecall

      – Dineshkani
      Sep 29 '16 at 4:17








    3




    3





    +1 for this answer, this is correct. however, i would update the line with dfd.notify(data) to dfd.resolve(data)

    – Jason
    Sep 25 '13 at 21:50







    +1 for this answer, this is correct. however, i would update the line with dfd.notify(data) to dfd.resolve(data)

    – Jason
    Sep 25 '13 at 21:50






    7




    7





    Is this a case of the code giving an illusion of being synchronous, without actually NOT being asynchronous ?

    – saurshaz
    Nov 29 '13 at 18:19





    Is this a case of the code giving an illusion of being synchronous, without actually NOT being asynchronous ?

    – saurshaz
    Nov 29 '13 at 18:19




    2




    2





    promises are IMO just well organised callbacks :) if you need an asynchronous call in let's say some object initialisation, than promises makes a little difference.

    – webduvet
    Sep 8 '14 at 10:24





    promises are IMO just well organised callbacks :) if you need an asynchronous call in let's say some object initialisation, than promises makes a little difference.

    – webduvet
    Sep 8 '14 at 10:24




    6




    6





    Promises are not sync.

    – Vans S
    May 16 '16 at 16:13





    Promises are not sync.

    – Vans S
    May 16 '16 at 16:13













    Try this github.com/dineshkani24/queuecall

    – Dineshkani
    Sep 29 '16 at 4:17





    Try this github.com/dineshkani24/queuecall

    – Dineshkani
    Sep 29 '16 at 4:17











    40














    Async functions, a feature in ES2017, make async code look sync by using promises (a particular form of async code) and the await keyword. Also notice in the code examples below the keyword async in front of the function keyword that signifies an async/await function. The await keyword won't work without being in a function pre-fixed with the async keyword. Since currently there is no exception to this that means no top level awaits will work (top level awaits meaning an await outside of any function). Though there is a proposal for top-level await.



    ES2017 was ratified (i.e. finalized) as the standard for JavaScript on June 27th, 2017. Async await may already work in your browser, but if not you can still use the functionality using a javascript transpiler like babel or traceur. Chrome 55 has full support of async functions. So if you have a newer browser you may be able to try out the code below.



    See kangax's es2017 compatibility table for browser compatibility.



    Here's an example async await function called doAsync which takes three one second pauses and prints the time difference after each pause from the start time:






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    async function doAsync () {
    var start = Date.now(), time;
    console.log(0);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    }

    doAsync();





    When the await keyword is placed before a promise value (in this case the promise value is the value returned by the function doSomethingAsync) the await keyword will pause execution of the function call, but it won't pause any other functions and it will continue executing other code until the promise resolves. After the promise resolves it will unwrap the value of the promise and you can think of the await and promise expression as now being replaced by that unwrapped value.



    So, since await just pauses waits for then unwraps a value before executing the rest of the line you can use it in for loops and inside function calls like in the below example which collects time differences awaited in an array and prints out the array.






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this calls each promise returning function one after the other
    async function doAsync () {
    var response = ;
    var start = Date.now();
    // each index is a promise returning function
    var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
    for(var i = 0; i < promiseFuncs.length; ++i) {
    var promiseFunc = promiseFuncs[i];
    response.push(await promiseFunc() - start);
    console.log(response);
    }
    // do something with response which is an array of values that were from resolved promises.
    return response
    }

    doAsync().then(function (response) {
    console.log(response)
    })





    The async function itself returns a promise so you can use that as a promise with chaining like I do above or within another async await function.



    The function above would wait for each response before sending another request if you would like to send the requests concurrently you can use Promise.all.






    // no change
    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    // no change
    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this function calls the async promise returning functions all at around the same time
    async function doAsync () {
    var start = Date.now();
    // we are now using promise all to await all promises to settle
    var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
    return responses.map(x=>x-start);
    }

    // no change
    doAsync().then(function (response) {
    console.log(response)
    })





    If the promise possibly rejects you can wrap it in a try catch or skip the try catch and let the error propagate to the async/await functions catch call. You should be careful not to leave promise errors unhandled especially in Node.js. Below are some examples that show off how errors work.






    function timeoutReject (time) {
    return new Promise(function (resolve, reject) {
    setTimeout(function () {
    reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
    }, time)
    })
    }

    function doErrorAsync () {
    return timeoutReject(1000);
    }

    var log = (...args)=>console.log(...args);
    var logErr = (...args)=>console.error(...args);

    async function unpropogatedError () {
    // promise is not awaited or returned so it does not propogate the error
    doErrorAsync();
    return "finished unpropogatedError successfully";
    }

    unpropogatedError().then(log).catch(logErr)

    async function handledError () {
    var start = Date.now();
    try {
    console.log((await doErrorAsync()) - start);
    console.log("past error");
    } catch (e) {
    console.log("in catch we handled the error");
    }

    return "finished handledError successfully";
    }

    handledError().then(log).catch(logErr)

    // example of how error propogates to chained catch method
    async function propogatedError () {
    var start = Date.now();
    var time = await doErrorAsync() - start;
    console.log(time - start);
    return "finished propogatedError successfully";
    }

    // this is what prints propogatedError's error.
    propogatedError().then(log).catch(logErr)





    If you go here you can see the finished proposals for upcoming ECMAScript versions.



    An alternative to this that can be used with just ES2015 (ES6) is to use a special function which wraps a generator function. Generator functions have a yield keyword which may be used to replicate the await keyword with a surrounding function. The yield keyword and generator function are a lot more general purpose and can do many more things then just what the async await function does. If you want a generator function wrapper that can be used to replicate async await I would check out co.js. By the way co's function much like async await functions return a promise. Honestly though at this point browser compatibility is about the same for both generator functions and async functions so if you just want the async await functionality you should use Async functions without co.js.



    Browser support is actually pretty good now for Async functions (as of 2017) in all major current browsers (Chrome, Safari, and Edge) except IE.






    share|improve this answer





















    • 1





      I like this answer

      – ycomp
      Jul 10 '17 at 8:39






    • 1





      how far we've come :)

      – Derek
      Aug 21 '18 at 2:29
















    40














    Async functions, a feature in ES2017, make async code look sync by using promises (a particular form of async code) and the await keyword. Also notice in the code examples below the keyword async in front of the function keyword that signifies an async/await function. The await keyword won't work without being in a function pre-fixed with the async keyword. Since currently there is no exception to this that means no top level awaits will work (top level awaits meaning an await outside of any function). Though there is a proposal for top-level await.



    ES2017 was ratified (i.e. finalized) as the standard for JavaScript on June 27th, 2017. Async await may already work in your browser, but if not you can still use the functionality using a javascript transpiler like babel or traceur. Chrome 55 has full support of async functions. So if you have a newer browser you may be able to try out the code below.



    See kangax's es2017 compatibility table for browser compatibility.



    Here's an example async await function called doAsync which takes three one second pauses and prints the time difference after each pause from the start time:






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    async function doAsync () {
    var start = Date.now(), time;
    console.log(0);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    }

    doAsync();





    When the await keyword is placed before a promise value (in this case the promise value is the value returned by the function doSomethingAsync) the await keyword will pause execution of the function call, but it won't pause any other functions and it will continue executing other code until the promise resolves. After the promise resolves it will unwrap the value of the promise and you can think of the await and promise expression as now being replaced by that unwrapped value.



    So, since await just pauses waits for then unwraps a value before executing the rest of the line you can use it in for loops and inside function calls like in the below example which collects time differences awaited in an array and prints out the array.






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this calls each promise returning function one after the other
    async function doAsync () {
    var response = ;
    var start = Date.now();
    // each index is a promise returning function
    var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
    for(var i = 0; i < promiseFuncs.length; ++i) {
    var promiseFunc = promiseFuncs[i];
    response.push(await promiseFunc() - start);
    console.log(response);
    }
    // do something with response which is an array of values that were from resolved promises.
    return response
    }

    doAsync().then(function (response) {
    console.log(response)
    })





    The async function itself returns a promise so you can use that as a promise with chaining like I do above or within another async await function.



    The function above would wait for each response before sending another request if you would like to send the requests concurrently you can use Promise.all.






    // no change
    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    // no change
    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this function calls the async promise returning functions all at around the same time
    async function doAsync () {
    var start = Date.now();
    // we are now using promise all to await all promises to settle
    var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
    return responses.map(x=>x-start);
    }

    // no change
    doAsync().then(function (response) {
    console.log(response)
    })





    If the promise possibly rejects you can wrap it in a try catch or skip the try catch and let the error propagate to the async/await functions catch call. You should be careful not to leave promise errors unhandled especially in Node.js. Below are some examples that show off how errors work.






    function timeoutReject (time) {
    return new Promise(function (resolve, reject) {
    setTimeout(function () {
    reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
    }, time)
    })
    }

    function doErrorAsync () {
    return timeoutReject(1000);
    }

    var log = (...args)=>console.log(...args);
    var logErr = (...args)=>console.error(...args);

    async function unpropogatedError () {
    // promise is not awaited or returned so it does not propogate the error
    doErrorAsync();
    return "finished unpropogatedError successfully";
    }

    unpropogatedError().then(log).catch(logErr)

    async function handledError () {
    var start = Date.now();
    try {
    console.log((await doErrorAsync()) - start);
    console.log("past error");
    } catch (e) {
    console.log("in catch we handled the error");
    }

    return "finished handledError successfully";
    }

    handledError().then(log).catch(logErr)

    // example of how error propogates to chained catch method
    async function propogatedError () {
    var start = Date.now();
    var time = await doErrorAsync() - start;
    console.log(time - start);
    return "finished propogatedError successfully";
    }

    // this is what prints propogatedError's error.
    propogatedError().then(log).catch(logErr)





    If you go here you can see the finished proposals for upcoming ECMAScript versions.



    An alternative to this that can be used with just ES2015 (ES6) is to use a special function which wraps a generator function. Generator functions have a yield keyword which may be used to replicate the await keyword with a surrounding function. The yield keyword and generator function are a lot more general purpose and can do many more things then just what the async await function does. If you want a generator function wrapper that can be used to replicate async await I would check out co.js. By the way co's function much like async await functions return a promise. Honestly though at this point browser compatibility is about the same for both generator functions and async functions so if you just want the async await functionality you should use Async functions without co.js.



    Browser support is actually pretty good now for Async functions (as of 2017) in all major current browsers (Chrome, Safari, and Edge) except IE.






    share|improve this answer





















    • 1





      I like this answer

      – ycomp
      Jul 10 '17 at 8:39






    • 1





      how far we've come :)

      – Derek
      Aug 21 '18 at 2:29














    40












    40








    40







    Async functions, a feature in ES2017, make async code look sync by using promises (a particular form of async code) and the await keyword. Also notice in the code examples below the keyword async in front of the function keyword that signifies an async/await function. The await keyword won't work without being in a function pre-fixed with the async keyword. Since currently there is no exception to this that means no top level awaits will work (top level awaits meaning an await outside of any function). Though there is a proposal for top-level await.



    ES2017 was ratified (i.e. finalized) as the standard for JavaScript on June 27th, 2017. Async await may already work in your browser, but if not you can still use the functionality using a javascript transpiler like babel or traceur. Chrome 55 has full support of async functions. So if you have a newer browser you may be able to try out the code below.



    See kangax's es2017 compatibility table for browser compatibility.



    Here's an example async await function called doAsync which takes three one second pauses and prints the time difference after each pause from the start time:






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    async function doAsync () {
    var start = Date.now(), time;
    console.log(0);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    }

    doAsync();





    When the await keyword is placed before a promise value (in this case the promise value is the value returned by the function doSomethingAsync) the await keyword will pause execution of the function call, but it won't pause any other functions and it will continue executing other code until the promise resolves. After the promise resolves it will unwrap the value of the promise and you can think of the await and promise expression as now being replaced by that unwrapped value.



    So, since await just pauses waits for then unwraps a value before executing the rest of the line you can use it in for loops and inside function calls like in the below example which collects time differences awaited in an array and prints out the array.






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this calls each promise returning function one after the other
    async function doAsync () {
    var response = ;
    var start = Date.now();
    // each index is a promise returning function
    var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
    for(var i = 0; i < promiseFuncs.length; ++i) {
    var promiseFunc = promiseFuncs[i];
    response.push(await promiseFunc() - start);
    console.log(response);
    }
    // do something with response which is an array of values that were from resolved promises.
    return response
    }

    doAsync().then(function (response) {
    console.log(response)
    })





    The async function itself returns a promise so you can use that as a promise with chaining like I do above or within another async await function.



    The function above would wait for each response before sending another request if you would like to send the requests concurrently you can use Promise.all.






    // no change
    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    // no change
    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this function calls the async promise returning functions all at around the same time
    async function doAsync () {
    var start = Date.now();
    // we are now using promise all to await all promises to settle
    var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
    return responses.map(x=>x-start);
    }

    // no change
    doAsync().then(function (response) {
    console.log(response)
    })





    If the promise possibly rejects you can wrap it in a try catch or skip the try catch and let the error propagate to the async/await functions catch call. You should be careful not to leave promise errors unhandled especially in Node.js. Below are some examples that show off how errors work.






    function timeoutReject (time) {
    return new Promise(function (resolve, reject) {
    setTimeout(function () {
    reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
    }, time)
    })
    }

    function doErrorAsync () {
    return timeoutReject(1000);
    }

    var log = (...args)=>console.log(...args);
    var logErr = (...args)=>console.error(...args);

    async function unpropogatedError () {
    // promise is not awaited or returned so it does not propogate the error
    doErrorAsync();
    return "finished unpropogatedError successfully";
    }

    unpropogatedError().then(log).catch(logErr)

    async function handledError () {
    var start = Date.now();
    try {
    console.log((await doErrorAsync()) - start);
    console.log("past error");
    } catch (e) {
    console.log("in catch we handled the error");
    }

    return "finished handledError successfully";
    }

    handledError().then(log).catch(logErr)

    // example of how error propogates to chained catch method
    async function propogatedError () {
    var start = Date.now();
    var time = await doErrorAsync() - start;
    console.log(time - start);
    return "finished propogatedError successfully";
    }

    // this is what prints propogatedError's error.
    propogatedError().then(log).catch(logErr)





    If you go here you can see the finished proposals for upcoming ECMAScript versions.



    An alternative to this that can be used with just ES2015 (ES6) is to use a special function which wraps a generator function. Generator functions have a yield keyword which may be used to replicate the await keyword with a surrounding function. The yield keyword and generator function are a lot more general purpose and can do many more things then just what the async await function does. If you want a generator function wrapper that can be used to replicate async await I would check out co.js. By the way co's function much like async await functions return a promise. Honestly though at this point browser compatibility is about the same for both generator functions and async functions so if you just want the async await functionality you should use Async functions without co.js.



    Browser support is actually pretty good now for Async functions (as of 2017) in all major current browsers (Chrome, Safari, and Edge) except IE.






    share|improve this answer















    Async functions, a feature in ES2017, make async code look sync by using promises (a particular form of async code) and the await keyword. Also notice in the code examples below the keyword async in front of the function keyword that signifies an async/await function. The await keyword won't work without being in a function pre-fixed with the async keyword. Since currently there is no exception to this that means no top level awaits will work (top level awaits meaning an await outside of any function). Though there is a proposal for top-level await.



    ES2017 was ratified (i.e. finalized) as the standard for JavaScript on June 27th, 2017. Async await may already work in your browser, but if not you can still use the functionality using a javascript transpiler like babel or traceur. Chrome 55 has full support of async functions. So if you have a newer browser you may be able to try out the code below.



    See kangax's es2017 compatibility table for browser compatibility.



    Here's an example async await function called doAsync which takes three one second pauses and prints the time difference after each pause from the start time:






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    async function doAsync () {
    var start = Date.now(), time;
    console.log(0);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    }

    doAsync();





    When the await keyword is placed before a promise value (in this case the promise value is the value returned by the function doSomethingAsync) the await keyword will pause execution of the function call, but it won't pause any other functions and it will continue executing other code until the promise resolves. After the promise resolves it will unwrap the value of the promise and you can think of the await and promise expression as now being replaced by that unwrapped value.



    So, since await just pauses waits for then unwraps a value before executing the rest of the line you can use it in for loops and inside function calls like in the below example which collects time differences awaited in an array and prints out the array.






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this calls each promise returning function one after the other
    async function doAsync () {
    var response = ;
    var start = Date.now();
    // each index is a promise returning function
    var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
    for(var i = 0; i < promiseFuncs.length; ++i) {
    var promiseFunc = promiseFuncs[i];
    response.push(await promiseFunc() - start);
    console.log(response);
    }
    // do something with response which is an array of values that were from resolved promises.
    return response
    }

    doAsync().then(function (response) {
    console.log(response)
    })





    The async function itself returns a promise so you can use that as a promise with chaining like I do above or within another async await function.



    The function above would wait for each response before sending another request if you would like to send the requests concurrently you can use Promise.all.






    // no change
    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    // no change
    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this function calls the async promise returning functions all at around the same time
    async function doAsync () {
    var start = Date.now();
    // we are now using promise all to await all promises to settle
    var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
    return responses.map(x=>x-start);
    }

    // no change
    doAsync().then(function (response) {
    console.log(response)
    })





    If the promise possibly rejects you can wrap it in a try catch or skip the try catch and let the error propagate to the async/await functions catch call. You should be careful not to leave promise errors unhandled especially in Node.js. Below are some examples that show off how errors work.






    function timeoutReject (time) {
    return new Promise(function (resolve, reject) {
    setTimeout(function () {
    reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
    }, time)
    })
    }

    function doErrorAsync () {
    return timeoutReject(1000);
    }

    var log = (...args)=>console.log(...args);
    var logErr = (...args)=>console.error(...args);

    async function unpropogatedError () {
    // promise is not awaited or returned so it does not propogate the error
    doErrorAsync();
    return "finished unpropogatedError successfully";
    }

    unpropogatedError().then(log).catch(logErr)

    async function handledError () {
    var start = Date.now();
    try {
    console.log((await doErrorAsync()) - start);
    console.log("past error");
    } catch (e) {
    console.log("in catch we handled the error");
    }

    return "finished handledError successfully";
    }

    handledError().then(log).catch(logErr)

    // example of how error propogates to chained catch method
    async function propogatedError () {
    var start = Date.now();
    var time = await doErrorAsync() - start;
    console.log(time - start);
    return "finished propogatedError successfully";
    }

    // this is what prints propogatedError's error.
    propogatedError().then(log).catch(logErr)





    If you go here you can see the finished proposals for upcoming ECMAScript versions.



    An alternative to this that can be used with just ES2015 (ES6) is to use a special function which wraps a generator function. Generator functions have a yield keyword which may be used to replicate the await keyword with a surrounding function. The yield keyword and generator function are a lot more general purpose and can do many more things then just what the async await function does. If you want a generator function wrapper that can be used to replicate async await I would check out co.js. By the way co's function much like async await functions return a promise. Honestly though at this point browser compatibility is about the same for both generator functions and async functions so if you just want the async await functionality you should use Async functions without co.js.



    Browser support is actually pretty good now for Async functions (as of 2017) in all major current browsers (Chrome, Safari, and Edge) except IE.






    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    async function doAsync () {
    var start = Date.now(), time;
    console.log(0);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    }

    doAsync();





    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    async function doAsync () {
    var start = Date.now(), time;
    console.log(0);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    time = await doSomethingAsync();
    console.log(time - start);
    }

    doAsync();





    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this calls each promise returning function one after the other
    async function doAsync () {
    var response = ;
    var start = Date.now();
    // each index is a promise returning function
    var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
    for(var i = 0; i < promiseFuncs.length; ++i) {
    var promiseFunc = promiseFuncs[i];
    response.push(await promiseFunc() - start);
    console.log(response);
    }
    // do something with response which is an array of values that were from resolved promises.
    return response
    }

    doAsync().then(function (response) {
    console.log(response)
    })





    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this calls each promise returning function one after the other
    async function doAsync () {
    var response = ;
    var start = Date.now();
    // each index is a promise returning function
    var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
    for(var i = 0; i < promiseFuncs.length; ++i) {
    var promiseFunc = promiseFuncs[i];
    response.push(await promiseFunc() - start);
    console.log(response);
    }
    // do something with response which is an array of values that were from resolved promises.
    return response
    }

    doAsync().then(function (response) {
    console.log(response)
    })





    // no change
    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    // no change
    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this function calls the async promise returning functions all at around the same time
    async function doAsync () {
    var start = Date.now();
    // we are now using promise all to await all promises to settle
    var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
    return responses.map(x=>x-start);
    }

    // no change
    doAsync().then(function (response) {
    console.log(response)
    })





    // no change
    function timeoutPromise (time) {
    return new Promise(function (resolve) {
    setTimeout(function () {
    resolve(Date.now());
    }, time)
    })
    }

    // no change
    function doSomethingAsync () {
    return timeoutPromise(1000);
    }

    // this function calls the async promise returning functions all at around the same time
    async function doAsync () {
    var start = Date.now();
    // we are now using promise all to await all promises to settle
    var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
    return responses.map(x=>x-start);
    }

    // no change
    doAsync().then(function (response) {
    console.log(response)
    })





    function timeoutReject (time) {
    return new Promise(function (resolve, reject) {
    setTimeout(function () {
    reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
    }, time)
    })
    }

    function doErrorAsync () {
    return timeoutReject(1000);
    }

    var log = (...args)=>console.log(...args);
    var logErr = (...args)=>console.error(...args);

    async function unpropogatedError () {
    // promise is not awaited or returned so it does not propogate the error
    doErrorAsync();
    return "finished unpropogatedError successfully";
    }

    unpropogatedError().then(log).catch(logErr)

    async function handledError () {
    var start = Date.now();
    try {
    console.log((await doErrorAsync()) - start);
    console.log("past error");
    } catch (e) {
    console.log("in catch we handled the error");
    }

    return "finished handledError successfully";
    }

    handledError().then(log).catch(logErr)

    // example of how error propogates to chained catch method
    async function propogatedError () {
    var start = Date.now();
    var time = await doErrorAsync() - start;
    console.log(time - start);
    return "finished propogatedError successfully";
    }

    // this is what prints propogatedError's error.
    propogatedError().then(log).catch(logErr)





    function timeoutReject (time) {
    return new Promise(function (resolve, reject) {
    setTimeout(function () {
    reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
    }, time)
    })
    }

    function doErrorAsync () {
    return timeoutReject(1000);
    }

    var log = (...args)=>console.log(...args);
    var logErr = (...args)=>console.error(...args);

    async function unpropogatedError () {
    // promise is not awaited or returned so it does not propogate the error
    doErrorAsync();
    return "finished unpropogatedError successfully";
    }

    unpropogatedError().then(log).catch(logErr)

    async function handledError () {
    var start = Date.now();
    try {
    console.log((await doErrorAsync()) - start);
    console.log("past error");
    } catch (e) {
    console.log("in catch we handled the error");
    }

    return "finished handledError successfully";
    }

    handledError().then(log).catch(logErr)

    // example of how error propogates to chained catch method
    async function propogatedError () {
    var start = Date.now();
    var time = await doErrorAsync() - start;
    console.log(time - start);
    return "finished propogatedError successfully";
    }

    // this is what prints propogatedError's error.
    propogatedError().then(log).catch(logErr)






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 24 '18 at 22:35

























    answered Nov 7 '15 at 6:06









    JohnJohn

    4,1532746




    4,1532746








    • 1





      I like this answer

      – ycomp
      Jul 10 '17 at 8:39






    • 1





      how far we've come :)

      – Derek
      Aug 21 '18 at 2:29














    • 1





      I like this answer

      – ycomp
      Jul 10 '17 at 8:39






    • 1





      how far we've come :)

      – Derek
      Aug 21 '18 at 2:29








    1




    1





    I like this answer

    – ycomp
    Jul 10 '17 at 8:39





    I like this answer

    – ycomp
    Jul 10 '17 at 8:39




    1




    1





    how far we've come :)

    – Derek
    Aug 21 '18 at 2:29





    how far we've come :)

    – Derek
    Aug 21 '18 at 2:29











    6














    There is one nice workaround at http://taskjs.org/



    It uses generators which are new to javascript. So it's currently not implemented by most browsers. I tested it in firefox, and for me it is nice way to wrap asynchronous function.



    Here is example code from project GitHub



    var { Deferred } = task;

    spawn(function() {
    out.innerHTML = "reading...n";
    try {
    var d = yield read("read.html");
    alert(d.responseText.length);
    } catch (e) {
    e.stack.split(/n/).forEach(function(line) { console.log(line) });
    console.log("");
    out.innerHTML = "error: " + e;
    }

    });

    function read(url, method) {
    method = method || "GET";
    var xhr = new XMLHttpRequest();
    var deferred = new Deferred();
    xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
    if (xhr.status >= 400) {
    var e = new Error(xhr.statusText);
    e.status = xhr.status;
    deferred.reject(e);
    } else {
    deferred.resolve({
    responseText: xhr.responseText
    });
    }
    }
    };
    xhr.open(method, url, true);
    xhr.send();
    return deferred.promise;
    }





    share|improve this answer






























      6














      There is one nice workaround at http://taskjs.org/



      It uses generators which are new to javascript. So it's currently not implemented by most browsers. I tested it in firefox, and for me it is nice way to wrap asynchronous function.



      Here is example code from project GitHub



      var { Deferred } = task;

      spawn(function() {
      out.innerHTML = "reading...n";
      try {
      var d = yield read("read.html");
      alert(d.responseText.length);
      } catch (e) {
      e.stack.split(/n/).forEach(function(line) { console.log(line) });
      console.log("");
      out.innerHTML = "error: " + e;
      }

      });

      function read(url, method) {
      method = method || "GET";
      var xhr = new XMLHttpRequest();
      var deferred = new Deferred();
      xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
      if (xhr.status >= 400) {
      var e = new Error(xhr.statusText);
      e.status = xhr.status;
      deferred.reject(e);
      } else {
      deferred.resolve({
      responseText: xhr.responseText
      });
      }
      }
      };
      xhr.open(method, url, true);
      xhr.send();
      return deferred.promise;
      }





      share|improve this answer




























        6












        6








        6







        There is one nice workaround at http://taskjs.org/



        It uses generators which are new to javascript. So it's currently not implemented by most browsers. I tested it in firefox, and for me it is nice way to wrap asynchronous function.



        Here is example code from project GitHub



        var { Deferred } = task;

        spawn(function() {
        out.innerHTML = "reading...n";
        try {
        var d = yield read("read.html");
        alert(d.responseText.length);
        } catch (e) {
        e.stack.split(/n/).forEach(function(line) { console.log(line) });
        console.log("");
        out.innerHTML = "error: " + e;
        }

        });

        function read(url, method) {
        method = method || "GET";
        var xhr = new XMLHttpRequest();
        var deferred = new Deferred();
        xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
        if (xhr.status >= 400) {
        var e = new Error(xhr.statusText);
        e.status = xhr.status;
        deferred.reject(e);
        } else {
        deferred.resolve({
        responseText: xhr.responseText
        });
        }
        }
        };
        xhr.open(method, url, true);
        xhr.send();
        return deferred.promise;
        }





        share|improve this answer















        There is one nice workaround at http://taskjs.org/



        It uses generators which are new to javascript. So it's currently not implemented by most browsers. I tested it in firefox, and for me it is nice way to wrap asynchronous function.



        Here is example code from project GitHub



        var { Deferred } = task;

        spawn(function() {
        out.innerHTML = "reading...n";
        try {
        var d = yield read("read.html");
        alert(d.responseText.length);
        } catch (e) {
        e.stack.split(/n/).forEach(function(line) { console.log(line) });
        console.log("");
        out.innerHTML = "error: " + e;
        }

        });

        function read(url, method) {
        method = method || "GET";
        var xhr = new XMLHttpRequest();
        var deferred = new Deferred();
        xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
        if (xhr.status >= 400) {
        var e = new Error(xhr.statusText);
        e.status = xhr.status;
        deferred.reject(e);
        } else {
        deferred.resolve({
        responseText: xhr.responseText
        });
        }
        }
        };
        xhr.open(method, url, true);
        xhr.send();
        return deferred.promise;
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jun 10 '13 at 21:45

























        answered Jun 10 '13 at 20:27









        George VinokhodovGeorge Vinokhodov

        11728




        11728























            -1














            The idea that you hope to achieve can be made possible if you tweak the requirement a little bit



            The below code is possible if your runtime supports the ES6 specification.



            More about async functions



            async function myAsynchronousCall(param1) {
            // logic for myAsynchronous call
            return d;
            }

            function doSomething() {

            var data = await myAsynchronousCall(param1); //'blocks' here until the async call is finished
            return data;
            }





            share|improve this answer



















            • 2





              Firefox gives the error: SyntaxError: await is only valid in async functions and async generators. Not to mention that param1 is not defined (and not even used).

              – Harvey
              Jan 24 at 0:39
















            -1














            The idea that you hope to achieve can be made possible if you tweak the requirement a little bit



            The below code is possible if your runtime supports the ES6 specification.



            More about async functions



            async function myAsynchronousCall(param1) {
            // logic for myAsynchronous call
            return d;
            }

            function doSomething() {

            var data = await myAsynchronousCall(param1); //'blocks' here until the async call is finished
            return data;
            }





            share|improve this answer



















            • 2





              Firefox gives the error: SyntaxError: await is only valid in async functions and async generators. Not to mention that param1 is not defined (and not even used).

              – Harvey
              Jan 24 at 0:39














            -1












            -1








            -1







            The idea that you hope to achieve can be made possible if you tweak the requirement a little bit



            The below code is possible if your runtime supports the ES6 specification.



            More about async functions



            async function myAsynchronousCall(param1) {
            // logic for myAsynchronous call
            return d;
            }

            function doSomething() {

            var data = await myAsynchronousCall(param1); //'blocks' here until the async call is finished
            return data;
            }





            share|improve this answer













            The idea that you hope to achieve can be made possible if you tweak the requirement a little bit



            The below code is possible if your runtime supports the ES6 specification.



            More about async functions



            async function myAsynchronousCall(param1) {
            // logic for myAsynchronous call
            return d;
            }

            function doSomething() {

            var data = await myAsynchronousCall(param1); //'blocks' here until the async call is finished
            return data;
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Aug 29 '18 at 11:39









            eragon512eragon512

            231




            231








            • 2





              Firefox gives the error: SyntaxError: await is only valid in async functions and async generators. Not to mention that param1 is not defined (and not even used).

              – Harvey
              Jan 24 at 0:39














            • 2





              Firefox gives the error: SyntaxError: await is only valid in async functions and async generators. Not to mention that param1 is not defined (and not even used).

              – Harvey
              Jan 24 at 0:39








            2




            2





            Firefox gives the error: SyntaxError: await is only valid in async functions and async generators. Not to mention that param1 is not defined (and not even used).

            – Harvey
            Jan 24 at 0:39





            Firefox gives the error: SyntaxError: await is only valid in async functions and async generators. Not to mention that param1 is not defined (and not even used).

            – Harvey
            Jan 24 at 0:39











            -2














            Use Async Await and Promise.resolve / Promise.all 😊






            share|improve this answer


























            • Callbacks are asynchronous in JS. stackoverflow.com/a/36213995/2963111 - "In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked." You're just recommending changing the function to use older callback style code, rather than promises.

              – Harvey
              Jan 24 at 0:42


















            -2














            Use Async Await and Promise.resolve / Promise.all 😊






            share|improve this answer


























            • Callbacks are asynchronous in JS. stackoverflow.com/a/36213995/2963111 - "In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked." You're just recommending changing the function to use older callback style code, rather than promises.

              – Harvey
              Jan 24 at 0:42
















            -2












            -2








            -2







            Use Async Await and Promise.resolve / Promise.all 😊






            share|improve this answer















            Use Async Await and Promise.resolve / Promise.all 😊







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Feb 9 at 9:16

























            answered Feb 6 '18 at 12:11









            Thomas GotwigThomas Gotwig

            36727




            36727













            • Callbacks are asynchronous in JS. stackoverflow.com/a/36213995/2963111 - "In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked." You're just recommending changing the function to use older callback style code, rather than promises.

              – Harvey
              Jan 24 at 0:42





















            • Callbacks are asynchronous in JS. stackoverflow.com/a/36213995/2963111 - "In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked." You're just recommending changing the function to use older callback style code, rather than promises.

              – Harvey
              Jan 24 at 0:42



















            Callbacks are asynchronous in JS. stackoverflow.com/a/36213995/2963111 - "In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked." You're just recommending changing the function to use older callback style code, rather than promises.

            – Harvey
            Jan 24 at 0:42







            Callbacks are asynchronous in JS. stackoverflow.com/a/36213995/2963111 - "In Javascript, on the other hand, callbacks are usually asynchronous - you pass a function that will be invoked ... but other events will continue to be processed until the callback is invoked." You're just recommending changing the function to use older callback style code, rather than promises.

            – Harvey
            Jan 24 at 0:42




















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9121902%2fcall-an-asynchronous-javascript-function-synchronously%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            Npm cannot find a required file even through it is in the searched directory