[javascript] How do I return the response from an asynchronous call?

I have a function foo which makes an asynchronous request. How can I return the response/result from foo?

I tried returning the value from the callback, as well as assigning the result to a local variable inside the function and returning that one, but none of those ways actually return the response (they all return undefined or whatever the initial value of the variable result is).

Example using jQuery's ajax function:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            result = response;
            // return response; // <- I tried that one as well
        }
    });

    return result; // It always returns `undefined`
}

Example using node.js:

function foo() {
    var result;

    fs.readFile("path/to/file", function(err, data) {
        result = data;
        // return data; // <- I tried that one as well
    });

    return result; // It always returns `undefined`
}

Example using the then block of a promise:

function foo() {
    var result;

    fetch(url).then(function(response) {
        result = response;
        // return response; // <- I tried that one as well
    });

    return result; // It always returns `undefined`
}

This question is related to javascript jquery ajax asynchronous

The answer is


I will answer with a horrible-looking, hand-drawn comic. The second image is the reason why result is undefined in your code example.

enter image description here


Use a callback() function inside the foo() success. Try in this way. It is simple and easy to understand.  

var lat = "";
var lon = "";
function callback(data) {
    lat = data.lat;
    lon = data.lon;
}
function getLoc() {
    var url = "http://ip-api.com/json"
    $.getJSON(url, function(data) {
        callback(data);
    });
}

getLoc();

Short answer: Your foo() method returns immediately, while the $ajax() call executes asynchronously after the function returns. The problem is then how or where to store the results retrieved by the async call once it returns.

Several solutions have been given in this thread. Perhaps the easiest way is to pass an object to the foo() method, and to store the results in a member of that object after the async call completes.

function foo(result) {
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;   // Store the async result
        }
    });
}

var result = { response: null };   // Object to hold the async result
foo(result);                       // Returns before the async completes

Note that the call to foo() will still return nothing useful. However, the result of the async call will now be stored in result.response.


Angular1

For people who are using AngularJS, can handle this situation using Promises.

Here it says,

Promises can be used to unnest asynchronous functions and allows one to chain multiple functions together.

You can find a nice explanation here also.

Example found in docs mentioned below.

  promiseB = promiseA.then(
    function onSuccess(result) {
      return result + 1;
    }
    ,function onError(err) {
      //Handle error
    }
  );

 // promiseB will be resolved immediately after promiseA is resolved 
 // and its value will be the result of promiseA incremented by 1.

Angular2 and Later

In Angular2 with look at the following example, but its recommended to use Observables with Angular2.

 search(term: string) {
     return this.http
  .get(`https://api.spotify.com/v1/search?q=${term}&type=artist`)
  .map((response) => response.json())
  .toPromise();

}

You can consume that in this way,

search() {
    this.searchService.search(this.searchField.value)
      .then((result) => {
    this.result = result.artists.items;
  })
  .catch((error) => console.error(error));
}

See the original post here. But Typescript does not support native es6 Promises, if you want to use it, you might need plugin for that.

Additionally here is the promises spec define here.


This is one of the places which two ways data binding or store concept that's used in many new JavaScript frameworks will work great for you...

So if you are using Angular, React or any other frameworks which do two ways data binding or store concept this issue is simply fixed for you, so in easy word, your result is undefined at the first stage, so you have got result = undefined before you receive the data, then as soon as you get the result, it will be updated and get assigned to the new value which response of your Ajax call...

But how you can do it in pure javascript or jQuery for example as you asked in this question?

You can use a callback, promise and recently observable to handle it for you, for example in promises we have some function like success() or then() which will be executed when your data is ready for you, same with callback or subscribe function on observable.

For example in your case which you are using jQuery, you can do something like this:

$(document).ready(function(){
    function foo() {
        $.ajax({url: "api/data", success: function(data){
            fooDone(data); //after we have data, we pass it to fooDone
        }});
    };

    function fooDone(data) {
        console.log(data); //fooDone has the data and console.log it
    };

    foo(); //call happens here
});

For more information study about promises and observables which are newer ways to do this async stuffs.


async: false

I solved by setting async to false and restructure my ajax call :

I set global function called sendRequest(type, url, data) with three parameters to be called every time everywhere

function sendRequest(type, url, data) {
    let returnValue = null;
    $.ajax({
        url: url,
        type: type,
        async: false,
        data: data,
        dataType: 'json',
        success: function (resp) {
            returnValue = resp;
        }
    });
    return returnValue;
} 

Now call function

let password = $("#password").val();
        let email = $("#email").val();
        let data = {
            email: email,
            password: password,
        };
        let  resp =  sendRequest('POST', 'http://localhost/signin')}}", data);
        console.log(resp);

Important Note in code is : async: false


Using Promise

The most perfect answer to this question is using Promise.

function ajax(method, url, params) {
  return new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
      resolve(this.responseText);
    };
    xhr.onerror = reject;
    xhr.open(method, url);
    xhr.send(params);
  });
}

Usage

ajax("GET", "/test", "acrive=1").then(function(result) {
    // Code depending on result
})
.catch(function() {
    // An error occurred
});

But wait...!

There is a problem with using promises!

Why should we use our own custom Promise?

I was using this solution for a while until I figured out there is an error in old browsers:

Uncaught ReferenceError: Promise is not defined

So i decided to implement my own Promise class for ES3 to below js compilers if its not defined. Just add this code before your main code and then safely use Promise!

if(typeof Promise === "undefined"){
    function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) { 
            throw new TypeError("Cannot call a class as a function"); 
        }
    }
    var Promise = function () {
        function Promise(main) {
            var _this = this;
            _classCallCheck(this, Promise);
            this.value = undefined;
            this.callbacks = [];
            var resolve = function resolve(resolveValue) {
                _this.value = resolveValue;
                _this.triggerCallbacks();
            };
            var reject = function reject(rejectValue) {
                _this.value = rejectValue;
                _this.triggerCallbacks();
            };
            main(resolve, reject);
        }
        Promise.prototype.then = function then(cb) {
            var _this2 = this;
            var next = new Promise(function (resolve) {
                _this2.callbacks.push(function (x) {
                    return resolve(cb(x));
                });
            });
            return next;
        };
        Promise.prototype.catch = function catch_(cb) {
            var _this2 = this;
            var next = new Promise(function (reject) {
                _this2.callbacks.push(function (x) {
                    return reject(cb(x));
                });
            });
            return next;
        };
        Promise.prototype.triggerCallbacks = function triggerCallbacks() {
            var _this3 = this;
            this.callbacks.forEach(function (cb) {
                cb(_this3.value);
            });
        };
        return Promise;
    }();
}

Simple code example to convert XHR on Node to async-await

var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhttp = new XMLHttpRequest();

function xhrWrapWithPromise() {
  return new Promise((resolve, reject) => {
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4) {
        if (this.status == 200) {
          resolve(this.responseText);
        } else {
          reject(new Error("Couldn't feth data finally"));
        }
      }
    };
    xhttp.open("GET", "https://www.w3schools.com/xml/xmlhttp_info.txt", true);
    xhttp.send();
  });
}

//We need to wrap await in Async function so and anonymous IIFE here
(async _ => {
  try {
    let result = await xhrWrapWithPromise();
    console.log(result);
  } catch (error) {
    console.log(error);
  }
})();

While promises and callbacks work fine in many situations, it is a pain in the rear to express something like:

if (!name) {
  name = async1();
}
async2(name);

You'd end up going through async1; check if name is undefined or not and call the callback accordingly.

async1(name, callback) {
  if (name)
    callback(name)
  else {
    doSomething(callback)
  }
}

async1(name, async2)

While it is okay in small examples it gets annoying when you have a lot of similar cases and error handling involved.

Fibers helps in solving the issue.

var Fiber = require('fibers')

function async1(container) {
  var current = Fiber.current
  var result
  doSomething(function(name) {
    result = name
    fiber.run()
  })
  Fiber.yield()
  return result
}

Fiber(function() {
  var name
  if (!name) {
    name = async1()
  }
  async2(name)
  // Make any number of async calls from here
}

You can checkout the project here.


The following example I have written shows how to

  • Handle asynchronous HTTP calls;
  • Wait for response from each API call;
  • Use Promise pattern;
  • Use Promise.all pattern to join multiple HTTP calls;

This working example is self-contained. It will define a simple request object that uses the window XMLHttpRequest object to make calls. It will define a simple function to wait for a bunch of promises to be completed.

Context. The example is querying the Spotify Web API endpoint in order to search for playlist objects for a given set of query strings:

[
 "search?type=playlist&q=%22doom%20metal%22",
 "search?type=playlist&q=Adele"
]

For each item, a new Promise will fire a block - ExecutionBlock, parse the result, schedule a new set of promises based on the result array, that is a list of Spotify user objects and execute the new HTTP call within the ExecutionProfileBlock asynchronously.

You can then see a nested Promise structure, that lets you spawn multiple and completely asynchronous nested HTTP calls, and join the results from each subset of calls through Promise.all.

NOTE Recent Spotify search APIs will require an access token to be specified in the request headers:

-H "Authorization: Bearer {your access token}" 

So, you to run the following example you need to put your access token in the request headers:

_x000D_
_x000D_
var spotifyAccessToken = "YourSpotifyAccessToken";_x000D_
var console = {_x000D_
    log: function(s) {_x000D_
        document.getElementById("console").innerHTML += s + "<br/>"_x000D_
    }_x000D_
}_x000D_
_x000D_
// Simple XMLHttpRequest_x000D_
// based on https://davidwalsh.name/xmlhttprequest_x000D_
SimpleRequest = {_x000D_
    call: function(what, response) {_x000D_
        var request;_x000D_
        if (window.XMLHttpRequest) { // Mozilla, Safari, ..._x000D_
            request = new XMLHttpRequest();_x000D_
        } else if (window.ActiveXObject) { // Internet Explorer_x000D_
            try {_x000D_
                request = new ActiveXObject('Msxml2.XMLHTTP');_x000D_
            }_x000D_
            catch (e) {_x000D_
                try {_x000D_
                  request = new ActiveXObject('Microsoft.XMLHTTP');_x000D_
                } catch (e) {}_x000D_
            }_x000D_
        }_x000D_
_x000D_
        // State changes_x000D_
        request.onreadystatechange = function() {_x000D_
            if (request.readyState === 4) { // Done_x000D_
                if (request.status === 200) { // Complete_x000D_
                    response(request.responseText)_x000D_
                }_x000D_
                else_x000D_
                    response();_x000D_
            }_x000D_
        }_x000D_
        request.open('GET', what, true);_x000D_
        request.setRequestHeader("Authorization", "Bearer " + spotifyAccessToken);_x000D_
        request.send(null);_x000D_
    }_x000D_
}_x000D_
_x000D_
//PromiseAll_x000D_
var promiseAll = function(items, block, done, fail) {_x000D_
    var self = this;_x000D_
    var promises = [],_x000D_
                   index = 0;_x000D_
    items.forEach(function(item) {_x000D_
        promises.push(function(item, i) {_x000D_
            return new Promise(function(resolve, reject) {_x000D_
                if (block) {_x000D_
                    block.apply(this, [item, index, resolve, reject]);_x000D_
                }_x000D_
            });_x000D_
        }(item, ++index))_x000D_
    });_x000D_
    Promise.all(promises).then(function AcceptHandler(results) {_x000D_
        if (done) done(results);_x000D_
    }, function ErrorHandler(error) {_x000D_
        if (fail) fail(error);_x000D_
    });_x000D_
}; //promiseAll_x000D_
_x000D_
// LP: deferred execution block_x000D_
var ExecutionBlock = function(item, index, resolve, reject) {_x000D_
    var url = "https://api.spotify.com/v1/"_x000D_
    url += item;_x000D_
    console.log( url )_x000D_
    SimpleRequest.call(url, function(result) {_x000D_
        if (result) {_x000D_
_x000D_
            var profileUrls = JSON.parse(result).playlists.items.map(function(item, index) {_x000D_
                return item.owner.href;_x000D_
            })_x000D_
            resolve(profileUrls);_x000D_
        }_x000D_
        else {_x000D_
            reject(new Error("call error"));_x000D_
        }_x000D_
    })_x000D_
}_x000D_
_x000D_
arr = [_x000D_
    "search?type=playlist&q=%22doom%20metal%22",_x000D_
    "search?type=playlist&q=Adele"_x000D_
]_x000D_
_x000D_
promiseAll(arr, function(item, index, resolve, reject) {_x000D_
    console.log("Making request [" + index + "]")_x000D_
    ExecutionBlock(item, index, resolve, reject);_x000D_
}, function(results) { // Aggregated results_x000D_
_x000D_
    console.log("All profiles received " + results.length);_x000D_
    //console.log(JSON.stringify(results[0], null, 2));_x000D_
_x000D_
    ///// promiseall again_x000D_
_x000D_
    var ExecutionProfileBlock = function(item, index, resolve, reject) {_x000D_
        SimpleRequest.call(item, function(result) {_x000D_
            if (result) {_x000D_
                var obj = JSON.parse(result);_x000D_
                resolve({_x000D_
                    name: obj.display_name,_x000D_
                    followers: obj.followers.total,_x000D_
                    url: obj.href_x000D_
                });_x000D_
            } //result_x000D_
        })_x000D_
    } //ExecutionProfileBlock_x000D_
_x000D_
    promiseAll(results[0], function(item, index, resolve, reject) {_x000D_
        //console.log("Making request [" + index + "] " + item)_x000D_
        ExecutionProfileBlock(item, index, resolve, reject);_x000D_
    }, function(results) { // aggregated results_x000D_
        console.log("All response received " + results.length);_x000D_
        console.log(JSON.stringify(results, null, 2));_x000D_
    }_x000D_
_x000D_
    , function(error) { // Error_x000D_
        console.log(error);_x000D_
    })_x000D_
_x000D_
    /////_x000D_
_x000D_
  },_x000D_
  function(error) { // Error_x000D_
      console.log(error);_x000D_
  });
_x000D_
<div id="console" />
_x000D_
_x000D_
_x000D_

I have extensively discussed this solution here.


Let's see the forest first before looking at the trees.

There are many informative answers with great details here, I won't repeat any of them. The key to programming in JavaScript is having first the correct mental model of overall execution.

  1. Your entry point(s) is executed as the result of an event. For example, a script tag with code is loaded into the browser. (Accordingly, this is why you may need to be concerned with the readiness of the page to run your code if it requires dom elements to be constructed first, etc.)
  2. Your code executes to completion--however many asynchronous calls it makes--without executing any of your callbacks, including XHR requests, set timeouts, dom event handlers, etc. Each of those callbacks waiting to be executed will sit in a queue, waiting their turn to be run after other events that fired have all finished execution.
  3. Each individual callback to an XHR request, set timeout or dom the event once invoked will then run to completion.

The good news is that if you understand this point well, you will never have to worry about race conditions. You should first and foremost thing of how you want to organize your code as essentially the response to different discrete events, and how you want to thread them together into a logical sequence. You can use promises or higher level new async/await as tools to that end, or you can roll your own.

But you shouldn't use any tactical tools to solve a problem until you are comfortable with the actual problem domain. Draw a map of these dependencies to know what needs to run when. Attempting an ad-hoc approach to all these callbacks is just not going to serve you well.


use of async/await with a transpilers like Babel to get it working in older browsers. You’ll also have to install this Babel preset and polyfill from npm: npm i -D babel-preset-env babel-polyfill.

function getData(ajaxurl) { 
  return $.ajax({
    url: ajaxurl,
    type: 'GET',
  });
};

async test() {
  try {
    const res = await getData('https://api.icndb.com/jokes/random')
    console.log(res)
  } catch(err) {
    console.log(err);
  }
}

test();

or the .then callback is just another way to write the same logic.

getData(ajaxurl).then(function(res) {
    console.log(res)
}

Another approach to return a value from an asynchronous function, is to pass in an object that will store the result from the asynchronous function.

Here is an example of the same:

var async = require("async");

// This wires up result back to the caller
var result = {};
var asyncTasks = [];
asyncTasks.push(function(_callback){
    // some asynchronous operation
    $.ajax({
        url: '...',
        success: function(response) {
            result.response = response;
            _callback();
        }
    });
});

async.parallel(asyncTasks, function(){
    // result is available after performing asynchronous operation
    console.log(result)
    console.log('Done');
});

I am using the result object to store the value during the asynchronous operation. This allows the result be available even after the asynchronous job.

I use this approach a lot. I would be interested to know how well this approach works where wiring the result back through consecutive modules is involved.


Here are some approaches to work with asynchronous requests:

  1. Browser Promise object
  2. Q - A promise library for JavaScript
  3. A+ Promises.js
  4. jQuery deferred
  5. XMLHttpRequest API
  6. Using callback concept - As implementation in first answer

Example: jQuery deferred implementation to work with multiple requests

_x000D_
_x000D_
var App = App || {};

App = {
    getDataFromServer: function(){

      var self = this,
                 deferred = $.Deferred(),
                 requests = [];

      requests.push($.getJSON('request/ajax/url/1'));
      requests.push($.getJSON('request/ajax/url/2'));

      $.when.apply(jQuery, requests).done(function(xhrResponse) {
        return deferred.resolve(xhrResponse.result);
      });
      return deferred;
    },

    init: function(){

        this.getDataFromServer().done(_.bind(function(resp1, resp2) {

           // Do the operations which you wanted to do when you
           // get a response from Ajax, for example, log response.
        }, this));
    }
};
App.init();
_x000D_
_x000D_
_x000D_


Most of the answers here give useful suggestions for when you have a single async operation, but sometimes, this comes up when you need to do an asynchronous operation for each entry in an array or other list-like structure. The temptation is to do this:

// WRONG
var results = [];
theArray.forEach(function(entry) {
    doSomethingAsync(entry, function(result) {
        results.push(result);
    });
});
console.log(results); // E.g., using them, returning them, etc.

Example:

_x000D_
_x000D_
// WRONG_x000D_
var theArray = [1, 2, 3];_x000D_
var results = [];_x000D_
theArray.forEach(function(entry) {_x000D_
    doSomethingAsync(entry, function(result) {_x000D_
        results.push(result);_x000D_
    });_x000D_
});_x000D_
console.log("Results:", results); // E.g., using them, returning them, etc._x000D_
_x000D_
function doSomethingAsync(value, callback) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    setTimeout(function() {_x000D_
        console.log("Completing async operation for " + value);_x000D_
        callback(value * 2);_x000D_
    }, Math.floor(Math.random() * 200));_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

The reason that doesn't work is that the callbacks from doSomethingAsync haven't run yet by the time you're trying to use the results.

So, if you have an array (or list of some kind) and want to do async operations for each entry, you have two options: Do the operations in parallel (overlapping), or in series (one after another in sequence).

Parallel

You can start all of them and keep track of how many callbacks you're expecting, and then use the results when you've gotten that many callbacks:

var results = [];
var expecting = theArray.length;
theArray.forEach(function(entry, index) {
    doSomethingAsync(entry, function(result) {
        results[index] = result;
        if (--expecting === 0) {
            // Done!
            console.log("Results:", results); // E.g., using the results
        }
    });
});

Example:

_x000D_
_x000D_
var theArray = [1, 2, 3];_x000D_
var results = [];_x000D_
var expecting = theArray.length;_x000D_
theArray.forEach(function(entry, index) {_x000D_
    doSomethingAsync(entry, function(result) {_x000D_
        results[index] = result;_x000D_
        if (--expecting === 0) {_x000D_
            // Done!_x000D_
            console.log("Results:", results); // E.g., using the results_x000D_
        }_x000D_
    });_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value, callback) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    setTimeout(function() {_x000D_
        console.log("Completing async operation for " + value);_x000D_
        callback(value * 2);_x000D_
    }, Math.floor(Math.random() * 200));_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

(We could do away with expecting and just use results.length === theArray.length, but that leaves us open to the possibility that theArray is changed while the calls are outstanding...)

Notice how we use the index from forEach to save the result in results in the same position as the entry it relates to, even if the results arrive out of order (since async calls don't necessarily complete in the order in which they were started).

But what if you need to return those results from a function? As the other answers have pointed out, you can't; you have to have your function accept and call a callback (or return a Promise). Here's a callback version:

function doSomethingWith(theArray, callback) {
    var results = [];
    var expecting = theArray.length;
    theArray.forEach(function(entry, index) {
        doSomethingAsync(entry, function(result) {
            results[index] = result;
            if (--expecting === 0) {
                // Done!
                callback(results);
            }
        });
    });
}
doSomethingWith(theArray, function(results) {
    console.log("Results:", results);
});

Example:

_x000D_
_x000D_
function doSomethingWith(theArray, callback) {_x000D_
    var results = [];_x000D_
    var expecting = theArray.length;_x000D_
    theArray.forEach(function(entry, index) {_x000D_
        doSomethingAsync(entry, function(result) {_x000D_
            results[index] = result;_x000D_
            if (--expecting === 0) {_x000D_
                // Done!_x000D_
                callback(results);_x000D_
            }_x000D_
        });_x000D_
    });_x000D_
}_x000D_
doSomethingWith([1, 2, 3], function(results) {_x000D_
    console.log("Results:", results);_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value, callback) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    setTimeout(function() {_x000D_
        console.log("Completing async operation for " + value);_x000D_
        callback(value * 2);_x000D_
    }, Math.floor(Math.random() * 200));_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

Or here's a version returning a Promise instead:

function doSomethingWith(theArray) {
    return new Promise(function(resolve) {
        var results = [];
        var expecting = theArray.length;
        theArray.forEach(function(entry, index) {
            doSomethingAsync(entry, function(result) {
                results[index] = result;
                if (--expecting === 0) {
                    // Done!
                    resolve(results);
                }
            });
        });
    });
}
doSomethingWith(theArray).then(function(results) {
    console.log("Results:", results);
});

Of course, if doSomethingAsync passed us errors, we'd use reject to reject the promise when we got an error.)

Example:

_x000D_
_x000D_
function doSomethingWith(theArray) {_x000D_
    return new Promise(function(resolve) {_x000D_
        var results = [];_x000D_
        var expecting = theArray.length;_x000D_
        theArray.forEach(function(entry, index) {_x000D_
            doSomethingAsync(entry, function(result) {_x000D_
                results[index] = result;_x000D_
                if (--expecting === 0) {_x000D_
                    // Done!_x000D_
                    resolve(results);_x000D_
                }_x000D_
            });_x000D_
        });_x000D_
    });_x000D_
}_x000D_
doSomethingWith([1, 2, 3]).then(function(results) {_x000D_
    console.log("Results:", results);_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value, callback) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    setTimeout(function() {_x000D_
        console.log("Completing async operation for " + value);_x000D_
        callback(value * 2);_x000D_
    }, Math.floor(Math.random() * 200));_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

(Or alternately, you could make a wrapper for doSomethingAsync that returns a promise, and then do the below...)

If doSomethingAsync gives you a Promise, you can use Promise.all:

function doSomethingWith(theArray) {
    return Promise.all(theArray.map(function(entry) {
        return doSomethingAsync(entry);
    }));
}
doSomethingWith(theArray).then(function(results) {
    console.log("Results:", results);
});

If you know that doSomethingAsync will ignore a second and third argument, you can just pass it directly to map (map calls its callback with three arguments, but most people only use the first most of the time):

function doSomethingWith(theArray) {
    return Promise.all(theArray.map(doSomethingAsync));
}
doSomethingWith(theArray).then(function(results) {
    console.log("Results:", results);
});

Example:

_x000D_
_x000D_
function doSomethingWith(theArray) {_x000D_
    return Promise.all(theArray.map(doSomethingAsync));_x000D_
}_x000D_
doSomethingWith([1, 2, 3]).then(function(results) {_x000D_
    console.log("Results:", results);_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    return new Promise(function(resolve) {_x000D_
        setTimeout(function() {_x000D_
            console.log("Completing async operation for " + value);_x000D_
            resolve(value * 2);_x000D_
        }, Math.floor(Math.random() * 200));_x000D_
    });_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

Note that Promise.all resolves its promise with an array of the results of all of the promises you give it when they are all resolved, or rejects its promise when the first of the promises you give it rejects.

Series

Suppose you don't want the operations to be in parallel? If you want to run them one after another, you need to wait for each operation to complete before you start the next. Here's an example of a function that does that and calls a callback with the result:

function doSomethingWith(theArray, callback) {
    var results = [];
    doOne(0);
    function doOne(index) {
        if (index < theArray.length) {
            doSomethingAsync(theArray[index], function(result) {
                results.push(result);
                doOne(index + 1);
            });
        } else {
            // Done!
            callback(results);
        }
    }
}
doSomethingWith(theArray, function(results) {
    console.log("Results:", results);
});

(Since we're doing the work in series, we can just use results.push(result) since we know we won't get results out of order. In the above we could have used results[index] = result;, but in some of the following examples we don't have an index to use.)

Example:

_x000D_
_x000D_
function doSomethingWith(theArray, callback) {_x000D_
    var results = [];_x000D_
    doOne(0);_x000D_
    function doOne(index) {_x000D_
        if (index < theArray.length) {_x000D_
            doSomethingAsync(theArray[index], function(result) {_x000D_
                results.push(result);_x000D_
                doOne(index + 1);_x000D_
            });_x000D_
        } else {_x000D_
            // Done!_x000D_
            callback(results);_x000D_
        }_x000D_
    }_x000D_
}_x000D_
doSomethingWith([1, 2, 3], function(results) {_x000D_
    console.log("Results:", results);_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value, callback) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    setTimeout(function() {_x000D_
        console.log("Completing async operation for " + value);_x000D_
        callback(value * 2);_x000D_
    }, Math.floor(Math.random() * 200));_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

(Or, again, build a wrapper for doSomethingAsync that gives you a promise and do the below...)

If doSomethingAsync gives you a Promise, if you can use ES2017+ syntax (perhaps with a transpiler like Babel), you can use an async function with for-of and await:

async function doSomethingWith(theArray) {
    const results = [];
    for (const entry of theArray) {
        results.push(await doSomethingAsync(entry));
    }
    return results;
}
doSomethingWith(theArray).then(results => {
    console.log("Results:", results);
});

Example:

_x000D_
_x000D_
async function doSomethingWith(theArray) {_x000D_
    const results = [];_x000D_
    for (const entry of theArray) {_x000D_
        results.push(await doSomethingAsync(entry));_x000D_
    }_x000D_
    return results;_x000D_
}_x000D_
doSomethingWith([1, 2, 3]).then(function(results) {_x000D_
    console.log("Results:", results);_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    return new Promise(function(resolve) {_x000D_
        setTimeout(function() {_x000D_
            console.log("Completing async operation for " + value);_x000D_
            resolve(value * 2);_x000D_
        }, Math.floor(Math.random() * 200));_x000D_
    });_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

If you can't use ES2017+ syntax (yet), you can use a variation on the "Promise reduce" pattern (this is more complex than the usual Promise reduce because we're not passing the result from one into the next, but instead gathering up their results in an array):

function doSomethingWith(theArray) {
    return theArray.reduce(function(p, entry) {
        return p.then(function(results) {
            return doSomethingAsync(entry).then(function(result) {
                results.push(result);
                return results;
            });
        });
    }, Promise.resolve([]));
}
doSomethingWith(theArray).then(function(results) {
    console.log("Results:", results);
});

Example:

_x000D_
_x000D_
function doSomethingWith(theArray) {_x000D_
    return theArray.reduce(function(p, entry) {_x000D_
        return p.then(function(results) {_x000D_
            return doSomethingAsync(entry).then(function(result) {_x000D_
                results.push(result);_x000D_
                return results;_x000D_
            });_x000D_
        });_x000D_
    }, Promise.resolve([]));_x000D_
}_x000D_
doSomethingWith([1, 2, 3]).then(function(results) {_x000D_
    console.log("Results:", results);_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    return new Promise(function(resolve) {_x000D_
        setTimeout(function() {_x000D_
            console.log("Completing async operation for " + value);_x000D_
            resolve(value * 2);_x000D_
        }, Math.floor(Math.random() * 200));_x000D_
    });_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_

...which is less cumbersome with ES2015+ arrow functions:

function doSomethingWith(theArray) {
    return theArray.reduce((p, entry) => p.then(results => doSomethingAsync(entry).then(result => {
        results.push(result);
        return results;
    })), Promise.resolve([]));
}
doSomethingWith(theArray).then(results => {
    console.log("Results:", results);
});

Example:

_x000D_
_x000D_
function doSomethingWith(theArray) {_x000D_
    return theArray.reduce((p, entry) => p.then(results => doSomethingAsync(entry).then(result => {_x000D_
        results.push(result);_x000D_
        return results;_x000D_
    })), Promise.resolve([]));_x000D_
}_x000D_
doSomethingWith([1, 2, 3]).then(function(results) {_x000D_
    console.log("Results:", results);_x000D_
});_x000D_
_x000D_
function doSomethingAsync(value) {_x000D_
    console.log("Starting async operation for " + value);_x000D_
    return new Promise(function(resolve) {_x000D_
        setTimeout(function() {_x000D_
            console.log("Completing async operation for " + value);_x000D_
            resolve(value * 2);_x000D_
        }, Math.floor(Math.random() * 200));_x000D_
    });_x000D_
}
_x000D_
.as-console-wrapper {_x000D_
  max-height: 100% !important;_x000D_
}
_x000D_
_x000D_
_x000D_


Rather than throwing code at you, there are 2 concepts that are key to understanding how JS handles callbacks and asynchronicity. (is that even a word?)

The Event Loop and Concurrency Model

There are three things you need to be aware of; The queue; the event loop and the stack

In broad, simplistic terms, the event loop is like the project manager, it is constantly listening for any functions that want to run and communicates between the queue and the stack.

while (queue.waitForMessage()) {
   queue.processNextMessage();
}

Once it receives a message to run something it adds it to the queue. The queue is the list of things that are waiting to execute (like your AJAX request). imagine it like this:

 1. call foo.com/api/bar using foobarFunc
 2. Go perform an infinite loop
 ... and so on

When one of these messages is going to execute it pops the message from the queue and creates a stack, the stack is everything JS needs to execute to perform the instruction in the message. So in our example it's being told to call foobarFunc

function foobarFunc (var) {
  console.log(anotherFunction(var));
}

So anything that foobarFunc needs to execute (in our case anotherFunction) will get pushed onto the stack. executed, and then forgotten about - the event loop will then move onto the next thing in the queue (or listen for messages)

The key thing here is the order of execution. That is

WHEN is something going to run

When you make a call using AJAX to an external party or run any asynchronous code (a setTimeout for example), Javascript is dependant upon a response before it can proceed.

The big question is when will it get the response? The answer is we don't know - so the event loop is waiting for that message to say "hey run me". If JS just waited around for that message synchronously your app would freeze and it will suck. So JS carries on executing the next item in the queue whilst waiting for the message to get added back to the queue.

That's why with asynchronous functionality we use things called callbacks. - A function or handler that, when passed into another function, will be executed at a later date. A promise uses callbacks (functions passed to .then() for eg.) as a way to reason about this asynchronous behaviour in a more linear way. The promise is a way of saying "I promise to return something at some point" and the callback is how we handle that value that is eventually returned. jQuery uses specific callbacks called deffered.done deffered.fail and deffered.always (amongst others). You can see them all here

So what you need to do is pass a function that is promised to execute at some point with data that is passed to it.

Because a callback is not executed immediately but at a later time it's important to pass the reference to the function not it executed. so

function foo(bla) {
  console.log(bla)
}

so most of the time (but not always) you'll pass foo not foo()

Hopefully that will make some sense. When you encounter things like this that seem confusing - i highly recommend reading the documentation fully to at least get an understanding of it. It will make you a much better developer.


We find ourselves in a universe which appears to progress along a dimension we call "time". We don't really understand what time is, but we have developed abstractions and vocabulary that let us reason and talk about it: "past", "present", "future", "before", "after".

The computer systems we build--more and more--have time as an important dimension. Certain things are set up to happen in the future. Then other things need to happen after those first things eventually occur. This is the basic notion called "asynchronicity". In our increasingly networked world, the most common case of asynchronicity is waiting for some remote system to respond to some request.

Consider an example. You call the milkman and order some milk. When it comes, you want to put it in your coffee. You can't put the milk in your coffee right now, because it is not here yet. You have to wait for it to come before putting it in your coffee. In other words, the following won't work:

var milk = order_milk();
put_in_coffee(milk);

Because JS has no way to know that it needs to wait for order_milk to finish before it executes put_in_coffee. In other words, it does not know that order_milk is asynchronous--is something that is not going to result in milk until some future time. JS, and other declarative languages execute one statement after another without waiting.

The classic JS approach to this problem, taking advantage of the fact that JS supports functions as first-class objects which can be passed around, is to pass a function as a parameter to the asynchronous request, which it will then invoke when it has completed its task sometime in the future. That is the "callback" approach. It looks like this:

order_milk(put_in_coffee);

order_milk kicks off, orders the milk, then, when and only when it arrives, it invokes put_in_coffee.

The problem with this callback approach is that it pollutes the normal semantics of a function reporting its result with return; instead, functions must not reports their results by calling a callback given as a parameter. Also, this approach can rapidly become unwieldy when dealing with longer sequences of events. For example, let's say that I want to wait for the milk to be put in the coffee, and then and only then perform a third step, namely drinking the coffee. I end up needing to write something like this:

order_milk(function(milk) { put_in_coffee(milk, drink_coffee); }

where I am passing to put_in_coffee both the milk to put in it, and also the action (drink_coffee) to execute once the milk has been put in. Such code becomes hard to write, and read, and debug.

In this case, we could rewrite the code in the question as:

var answer;
$.ajax('/foo.json') . done(function(response) {
  callback(response.data);
});

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

Enter promises

This was the motivation for the notion of a "promise", which is a particular type of value which represents a future or asynchronous outcome of some sort. It can represent something that already happened, or that is going to happen in the future, or might never happen at all. Promises have a single method, named then, to which you pass an action to be executed when the outcome the promise represents has been realized.

In the case of our milk and coffee, we design order_milk to return a promise for the milk arriving, then specify put_in_coffee as a then action, as follows:

order_milk() . then(put_in_coffee)

One advantage of this is that we can string these together to create sequences of future occurrences ("chaining"):

order_milk() . then(put_in_coffee) . then(drink_coffee)

Let's apply promises to your particular problem. We will wrap our request logic inside a function, which returns a promise:

function get_data() {
  return $.ajax('/foo.json');
}

Actually, all we've done is added a return to the call to $.ajax. This works because jQuery's $.ajax already returns a kind of promise-like thing. (In practice, without getting into details, we would prefer to wrap this call so as for return a real promise, or use some alternative to $.ajax that does so.) Now, if we want to load the file and wait for it to finish and then do something, we can simply say

get_data() . then(do_something)

for instance,

get_data() . 
  then(function(data) { console.log(data); });

When using promises, we end up passing lots of functions into then, so it's often helpful to use the more compact ES6-style arrow functions:

get_data() . 
  then(data => console.log(data));

The async keyword

But there's still something vaguely dissatisfying about having to write code one way if synchronous and a quite different way if asynchronous. For synchronous, we write

a();
b();

but if a is asynchronous, with promises we have to write

a() . then(b);

Above, we said, "JS has no way to know that it needs to wait for the first call to finish before it executes the second". Wouldn't it be nice if there was some way to tell JS that? It turns out that there is--the await keyword, used inside a special type of function called an "async" function. This feature is part of the upcoming version of ES but is already available in transpilers such as Babel given the right presets. This allows us to simply write

async function morning_routine() {
  var milk   = await order_milk();
  var coffee = await put_in_coffee(milk);
  await drink(coffee);
}

In your case, you would be able to write something like

async function foo() {
  data = await get_data();
  console.log(data);
}

Originally, callback were used for asynchronous operations (e.g. in the XMLHttpRequest API). Now promise-based APIs like the browser's Fetch API have become the default solution and the nicer async/await syntax is supported by all modern browsers and on Node.Js (server side).

A common scenario - fetching JSON data from the server - can look like this:

async function fetchResource(url) {
  const res = await fetch(url);
  if (!res.ok) {
    throw new Error(res.statusText);
  }
  return res.json();
}

To use it in another function:

async function doSomething() {
  try {
    const data = await fetchResource("https://example.test/resource/1");
    // ...
  } catch (e) {
    // handle error
    ...
  }
}

If you design a modern API, it is strongly recommended to prefer promise-based style over callbacks. If you inherited an API that relies on callbacks, it is possible to wrap it as a promise:

function sleep(timeout) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, timeout);
  });
}

async function fetchAfterTwoSeconds(url) {
  await sleep(2000);
  return fetchResource(url);
}

In Node.Js, which historically relied exclusively on callbacks, that technique is so common that they added a helper function called util.promisify.


Short answer is, you have to implement a callback like this:

function callback(response) {
    // Here you can do what ever you want with the response object.
    console.log(response);
}

$.ajax({
    url: "...",
    success: callback
});

There is no way by which you can return the result of an ajax response from a function, the reason why this is not possible is because Ajax call ($.get() or $.post()) is an async call and calling the function that encapsulates the Ajax call returns even before the response is rendered.

In such scenarios, the only option is to return a promise object, which will resolve when the response arrives.

There are 2 ways by which the above issue can be resolved, in both cases it makes use of promise.

Both the code snippets provided are working including the josn url and can be directly copied to jsfiddle and tested.

Option #1: Return the Ajax call directly from the foo method, in the latest version of Jquery ajax call returns a promise object, which can be resolved using a .then function. the input parameter to the .then function is the call back to the resolve function.

    //decalre function foo
   function foo(url)
   {
     return $.get(url);
   }

   //invoke foo function, which returns a promise object
   //the then function accepts the call back to the resolve function
   foo('https://jsonplaceholder.typicode.com/todos/1')
   .then(function(response)
   {
    console.log(response);
   })

Option #2 - declare a promise object inside the function and encapsulate the Ajax call within that promise function and return the promise object.

   function foo1() {

   var promise = new Promise(function(resolve, reject)
   {

     $.ajax({
    url: 'https://jsonplaceholder.typicode.com/todos/1',
    success: function(response) {
        console.log(response);

        resolve(response);
        // return response; // <- I tried that one as well
      }
    });

   });



   return promise;
   }

   foo1()
   .then(function(response)
   {
     console.log('Promise Resolved');
     console.log(response);
   })

Have a look at this example:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope,$http) {

    var getJoke = function(){
        return $http.get('http://api.icndb.com/jokes/random').then(function(res){
            return res.data.value;  
        });
    }

    getJoke().then(function(res) {
        console.log(res.joke);
    });
});

As you can see getJoke is returning a resolved promise (it is resolved when returning res.data.value). So you wait until the $http.get request is completed and then console.log(res.joke) is executed (as a normal asynchronous flow).

This is the plnkr:

http://embed.plnkr.co/XlNR7HpCaIhJxskMJfSg/

ES6 way (async - await)

(function(){
  async function getJoke(){
    let response = await fetch('http://api.icndb.com/jokes/random');
    let data = await response.json();
    return data.value;
  }

  getJoke().then((joke) => {
    console.log(joke);
  });
})();

Here is an example that works:

const validateName = async userName => {
  const url = "abc/xyz";
  try {
    const response = await axios.get(url);
    return response.data
  } catch (err) {
    return false;
  }
};

validateName("user")
 .then(data => console.log(data))
 .catch(reason => console.log(reason.message))

If you're using promises, this answer is for you.

This means AngularJS, jQuery (with deferred), native XHR's replacement (fetch), EmberJS, BackboneJS's save or any node library that returns promises.

Your code should be something along the lines of this:

function foo() {
    var data;
    // or $.get(...).then, or request(...).then, or query(...).then
    fetch("/echo/json").then(function(response){
        data = response.json();
    });
    return data;
}

var result = foo(); // result is always undefined no matter what.

Felix Kling did a fine job writing an answer for people using jQuery with callbacks for AJAX. I have an answer for native XHR. This answer is for generic usage of promises either on the frontend or backend.


The core issue

The JavaScript concurrency model in the browser and on the server with NodeJS/io.js is asynchronous and reactive.

Whenever you call a method that returns a promise, the then handlers are always executed asynchronously - that is, after the code below them that is not in a .then handler.

This means when you're returning data the then handler you've defined did not execute yet. This in turn means that the value you're returning has not been set to the correct value in time.

Here is a simple analogy for the issue:

_x000D_
_x000D_
    function getFive(){_x000D_
        var data;_x000D_
        setTimeout(function(){ // set a timer for one second in the future_x000D_
           data = 5; // after a second, do this_x000D_
        }, 1000);_x000D_
        return data;_x000D_
    }_x000D_
    document.body.innerHTML = getFive(); // `undefined` here and not 5
_x000D_
_x000D_
_x000D_

The value of data is undefined since the data = 5 part has not executed yet. It will likely execute in a second but by that time it is irrelevant to the returned value.

Since the operation did not happen yet (AJAX, server call, IO, timer) you're returning the value before the request got the chance to tell your code what that value is.

One possible solution to this problem is to code re-actively , telling your program what to do when the calculation completed. Promises actively enable this by being temporal (time-sensitive) in nature.

Quick recap on promises

A Promise is a value over time. Promises have state, they start as pending with no value and can settle to:

  • fulfilled meaning that the computation completed successfully.
  • rejected meaning that the computation failed.

A promise can only change states once after which it will always stay at the same state forever. You can attach then handlers to promises to extract their value and handle errors. then handlers allow chaining of calls. Promises are created by using APIs that return them. For example, the more modern AJAX replacement fetch or jQuery's $.get return promises.

When we call .then on a promise and return something from it - we get a promise for the processed value. If we return another promise we'll get amazing things, but let's hold our horses.

With promises

Let's see how we can solve the above issue with promises. First, let's demonstrate our understanding of promise states from above by using the Promise constructor for creating a delay function:

function delay(ms){ // takes amount of milliseconds
    // returns a new promise
    return new Promise(function(resolve, reject){
        setTimeout(function(){ // when the time is up
            resolve(); // change the promise to the fulfilled state
        }, ms);
    });
}

Now, after we converted setTimeout to use promises, we can use then to make it count:

_x000D_
_x000D_
function delay(ms){ // takes amount of milliseconds_x000D_
  // returns a new promise_x000D_
  return new Promise(function(resolve, reject){_x000D_
    setTimeout(function(){ // when the time is up_x000D_
      resolve(); // change the promise to the fulfilled state_x000D_
    }, ms);_x000D_
  });_x000D_
}_x000D_
_x000D_
function getFive(){_x000D_
  // we're RETURNING the promise, remember, a promise is a wrapper over our value_x000D_
  return delay(100).then(function(){ // when the promise is ready_x000D_
      return 5; // return the value 5, promises are all about return values_x000D_
  })_x000D_
}_x000D_
// we _have_ to wrap it like this in the call site, we can't access the plain value_x000D_
getFive().then(function(five){ _x000D_
   document.body.innerHTML = five;_x000D_
});
_x000D_
_x000D_
_x000D_

Basically, instead of returning a value which we can't do because of the concurrency model - we're returning a wrapper for a value that we can unwrap with then. It's like a box you can open with then.

Applying this

This stands the same for your original API call, you can:

function foo() {
    // RETURN the promise
    return fetch("/echo/json").then(function(response){
        return response.json(); // process it inside the `then`
    });
}

foo().then(function(response){
    // access the value inside the `then`
})

So this works just as well. We've learned we can't return values from already asynchronous calls but we can use promises and chain them to perform processing. We now know how to return the response from an asynchronous call.

ES2015 (ES6)

ES6 introduces generators which are functions that can return in the middle and then resume the point they were at. This is typically useful for sequences, for example:

function* foo(){ // notice the star, this is ES6 so new browsers/node/io only
    yield 1;
    yield 2;
    while(true) yield 3;
}

Is a function that returns an iterator over the sequence 1,2,3,3,3,3,.... which can be iterated. While this is interesting on its own and opens room for a lot of possibility there is one particular interesting case.

If the sequence we're producing is a sequence of actions rather than numbers - we can pause the function whenever an action is yielded and wait for it before we resume the function. So instead of a sequence of numbers, we need a sequence of future values - that is: promises.

This somewhat tricky but very powerful trick lets us write asynchronous code in a synchronous manner. There are several "runners" that do this for you, writing one is a short few lines of code but is beyond the scope of this answer. I'll be using Bluebird's Promise.coroutine here, but there are other wrappers like co or Q.async.

var foo = coroutine(function*(){
    var data = yield fetch("/echo/json"); // notice the yield
    // code here only executes _after_ the request is done
    return data.json(); // data is defined
});

This method returns a promise itself, which we can consume from other coroutines. For example:

var main = coroutine(function*(){
   var bar = yield foo(); // wait our earlier coroutine, it returns a promise
   // server call done here, code below executes when done
   var baz = yield fetch("/api/users/"+bar.userid); // depends on foo's result
   console.log(baz); // runs after both requests done
});
main();

ES2016 (ES7)

In ES7, this is further standardized, there are several proposals right now but in all of them you can await promise. This is just "sugar" (nicer syntax) for the ES6 proposal above by adding the async and await keywords. Making the above example:

async function foo(){
    var data = await fetch("/echo/json"); // notice the await
    // code here only executes _after_ the request is done
    return data.json(); // data is defined
}

It still returns a promise just the same :)


Of course there are many approaches like synchronous request, promise, but from my experience I think you should use the callback approach. It's natural to asynchronous behavior of Javascript. So, your code snippet can be rewrite a little different:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}

You can use this custom library (written using Promise) to make a remote call.

function $http(apiConfig) {
    return new Promise(function (resolve, reject) {
        var client = new XMLHttpRequest();
        client.open(apiConfig.method, apiConfig.url);
        client.send();
        client.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                // Performs the function "resolve" when this.status is equal to 2xx.
                // Your logic here.
                resolve(this.response);
            }
            else {
                // Performs the function "reject" when this.status is different than 2xx.
                reject(this.statusText);
            }
        };
        client.onerror = function () {
            reject(this.statusText);
        };
    });
}

Simple usage example:

$http({
    method: 'get',
    url: 'google.com'
}).then(function(response) {
    console.log(response);
}, function(error) {
    console.log(error)
});

Js is a single threaded.

Browser can be divided into three parts:

1)Event Loop

2)Web API

3)Event Queue

Event Loop runs for forever i.e kind of infinite loop.Event Queue is where all your function are pushed on some event(example:click) this is one by one carried out of queue and put into Event loop which execute this function and prepares it self for next one after first one is executed.This means Execution of one function doesn't starts till the function before it in queue is executed in event loop.

Now let us think we pushed two functions in a queue one is for getting a data from server and another utilises that data.We pushed the serverRequest() function in queue first then utiliseData() function. serverRequest function goes in event loop and makes a call to server as we never know how much time it will take to get data from server so this process is expected to take time and so we busy our event loop thus hanging our page, that's where Web API come into role it take this function from event loop and deals with server making event loop free so that we can execute next function from queue.The next function in queue is utiliseData() which goes in loop but because of no data available it goes waste and execution of next function continues till end of the queue.(This is called Async calling i.e we can do something else till we get data)

Let suppose our serverRequest() function had a return statement in a code, when we get back data from server Web API will push it in queue at the end of queue. As it get pushed at end in queue we cannot utilise its data as there is no function left in our queue to utilise this data.Thus it is not possible to return something from Async Call.

Thus Solution to this is callback or promise.

A Image from one of the answers here, Correctly explains callback use... We give our function(function utilising data returned from server) to function calling server.

CallBack

 function doAjax(callbackFunc, method, url) {
  var xmlHttpReq = new XMLHttpRequest();
  xmlHttpReq.open(method, url);
  xmlHttpReq.onreadystatechange = function() {

      if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200) {
        callbackFunc(xmlHttpReq.responseText);
      }


  }
  xmlHttpReq.send(null);

}

In my Code it is called as

function loadMyJson(categoryValue){
  if(categoryValue==="veg")
  doAjax(print,"GET","http://localhost:3004/vegetables");
  else if(categoryValue==="fruits")
  doAjax(print,"GET","http://localhost:3004/fruits");
  else 
  console.log("Data not found");
}

Javscript.info callback


I think no matter what method or mechanism used, or whatever the framework is (Angular/React) that hides it from you, the following principle holds:

  1. In the flow of the program (think code or even the lowest level: machine code), the data may not arrive back 2 seconds later, 3 seconds later, or may not arrive at all, so there is no usual return to use in order to return the data.

  2. It is the classic "observer pattern". (It can be in the form of a "callback".) It is: "hey, I am interested in knowing a successful arrival of data; would you let me know when it does." So you register an observer to be notified (or a function to be called to notify about the successful arrival of the data.) You also usually register an observer for the failure of arrival of such data.

  3. When it is successful arrival of data, or a failure of the return of such data, the registered observers (or callbacks) are notified together with the data (or called with the data). If the observer is registered in the form of a callback function foo, then foo(data) will be called. If the observer is registered in the form of an object foo, then depending on the interface, it could be that foo.notify(data) is called.


It's a very common issue we face while struggling with the 'mysteries' of JavaScript. Let me try demystifying this mystery today.

Let's start with a simple JavaScript function:

function foo(){
// do something 
 return 'wohoo';
}

let bar = foo(); // bar is 'wohoo' here

That's a simple synchronous function call (where each line of code is 'finished with its job' before the next one in sequence), and the result is same as expected.

Now let's add a bit of twist, by introducing little delay in our function, so that all lines of code are not 'finished' in sequence. Thus, it will emulate the asynchronous behavior of function :

function foo(){
 setTimeout( ()=>{
   return 'wohoo';
  }, 1000 )
}

let bar = foo() // bar is undefined here

So there you go, that delay just broke the functionality we expected! But what exactly happened ? Well, it's actually pretty logical if you look at the code. the function foo(), upon execution, returns nothing (thus returned value is undefined), but it does start a timer, which executes a function after 1s to return 'wohoo'. But as you can see, the value that's assigned to bar is the immediately returned stuff from foo(), which is nothing i.e. just undefined.

So, how do we tackle this issue?

Let's ask our function for a PROMISE. Promise is really about what it means : it means that the function guarantees you to provide with any output it gets in future. so let's see it in action for our little problem above :

function foo(){
   return new Promise( (resolve, reject) => { // I want foo() to PROMISE me something
    setTimeout ( function(){ 
      // promise is RESOLVED , when execution reaches this line of code
       resolve('wohoo')// After 1 second, RESOLVE the promise with value 'wohoo'
    }, 1000 )
  })
}

let bar ; 
foo().then( res => {
 bar = res;
 console.log(bar) // will print 'wohoo'
});

Thus, the summary is - to tackle the asynchronous functions like ajax based calls etc., you can use a promise to resolve the value (which you intend to return). Thus, in short you resolve value instead of returning, in asynchronous functions.

UPDATE (Promises with async/await)

Apart from using then/catch to work with promises, there exists one more approach. The idea is to recognize an asynchronous function and then wait for the promises to resolve, before moving to the next line of code. It's still just the promises under the hood, but with a different syntactical approach. To make things clearer, you can find a comparison below:

then/catch version:

function saveUsers(){
     getUsers()
      .then(users => {
         saveSomewhere(users);
      })
      .catch(err => {
          console.error(err);
       })
 }

async/await version:

  async function saveUsers(){
     try{
        let users = await getUsers()
        saveSomewhere(users);
     }
     catch(err){
        console.error(err);
     }
  }

Since 'await' always returns a Promise, simply do an extra 'await' (inside an async function) to extract the value:

test(); // This alerts "hello"

// This is the outer function that wants to get the string result of inner()
async function test() {
    var str=await await inner();
    alert(str);
    } // test

// This ia an inner function that can do arbitrary async operations
async function inner() {
    return Promise.resolve('hello');
    }

The simplest solution is create a JavaScript function and call it for the Ajax success callback.

function callServerAsync(){
    $.ajax({
        url: '...',
        success: function(response) {

            successCallback(response);
        }
    });
}

function successCallback(responseObj){
    // Do something like read the response and show data
    alert(JSON.stringify(responseObj)); // Only applicable to JSON response
}

function foo(callback) {

    $.ajax({
        url: '...',
        success: function(response) {
           return callback(null, response);
        }
    });
}

var result = foo(function(err, result){
          if (!err)
           console.log(result);    
}); 

XMLHttpRequest 2 (first of all read the answers from Benjamin Gruenbaum & Felix Kling)

If you don't use jQuery and want a nice short XMLHttpRequest 2 which works on the modern browsers and also on the mobile browsers I suggest to use it this way:

function ajax(a, b, c){ // URL, callback, just a placeholder
  c = new XMLHttpRequest;
  c.open('GET', a);
  c.onload = b;
  c.send()
}

As you can see:

  1. It's shorter than all other functions Listed.
  2. The callback is set directly (so no extra unnecessary closures).
  3. It uses the new onload (so you don't have to check for readystate && status)
  4. There are some other situations which I don't remember that make the XMLHttpRequest 1 annoying.

There are two ways to get the response of this Ajax call (three using the XMLHttpRequest var name):

The simplest:

this.response

Or if for some reason you bind() the callback to a class:

e.target.response

Example:

function callback(e){
  console.log(this.response);
}
ajax('URL', callback);

Or (the above one is better anonymous functions are always a problem):

ajax('URL', function(e){console.log(this.response)});

Nothing easier.

Now some people will probably say that it's better to use onreadystatechange or the even the XMLHttpRequest variable name. That's wrong.

Check out XMLHttpRequest advanced features

It supported all *modern browsers. And I can confirm as I'm using this approach since XMLHttpRequest 2 exists. I never had any type of problem on all browsers I use.

onreadystatechange is only useful if you want to get the headers on state 2.

Using the XMLHttpRequest variable name is another big error as you need to execute the callback inside the onload/oreadystatechange closures else you lost it.


Now if you want something more complex using post and FormData you can easily extend this function:

function x(a, b, e, d, c){ // URL, callback, method, formdata or {key:val},placeholder
  c = new XMLHttpRequest;
  c.open(e||'get', a);
  c.onload = b;
  c.send(d||null)
}

Again ... it's a very short function, but it does get & post.

Examples of usage:

x(url, callback); // By default it's get so no need to set
x(url, callback, 'post', {'key': 'val'}); // No need to set post data

Or pass a full form element (document.getElementsByTagName('form')[0]):

var fd = new FormData(form);
x(url, callback, 'post', fd);

Or set some custom values:

var fd = new FormData();
fd.append('key', 'val')
x(url, callback, 'post', fd);

As you can see I didn't implement sync... it's a bad thing.

Having said that ... why don't do it the easy way?


As mentioned in the comment the use of error && synchronous does completely break the point of the answer. Which is a nice short way to use Ajax in the proper way?

Error handler

function x(a, b, e, d, c){ // URL, callback, method, formdata or {key:val}, placeholder
  c = new XMLHttpRequest;
  c.open(e||'get', a);
  c.onload = b;
  c.onerror = error;
  c.send(d||null)
}

function error(e){
  console.log('--Error--', this.type);
  console.log('this: ', this);
  console.log('Event: ', e)
}
function displayAjax(e){
  console.log(e, this);
}
x('WRONGURL', displayAjax);

In the above script, you have an error handler which is statically defined so it does not compromise the function. The error handler can be used for other functions too.

But to really get out an error the only way is to write a wrong URL in which case every browser throws an error.

Error handlers are maybe useful if you set custom headers, set the responseType to blob array buffer or whatever...

Even if you pass 'POSTAPAPAP' as the method it won't throw an error.

Even if you pass 'fdggdgilfdghfldj' as formdata it won't throw an error.

In the first case the error is inside the displayAjax() under this.statusText as Method not Allowed.

In the second case, it simply works. You have to check at the server side if you passed the right post data.

cross-domain not allowed throws error automatically.

In the error response, there are no error codes.

There is only the this.type which is set to error.

Why add an error handler if you totally have no control over errors? Most of the errors are returned inside this in the callback function displayAjax().

So: No need for error checks if you're able to copy and paste the URL properly. ;)

PS: As the first test I wrote x('x', displayAjax)..., and it totally got a response...??? So I checked the folder where the HTML is located, and there was a file called 'x.xml'. So even if you forget the extension of your file XMLHttpRequest 2 WILL FIND IT. I LOL'd


Read a file synchronous

Don't do that.

If you want to block the browser for a while load a nice big .txt file synchronous.

function omg(a, c){ // URL
  c = new XMLHttpRequest;
  c.open('GET', a, true);
  c.send();
  return c; // Or c.response
}

Now you can do

 var res = omg('thisIsGonnaBlockThePage.txt');

There is no other way to do this in a non-asynchronous way. (Yeah, with setTimeout loop... but seriously?)

Another point is... if you work with APIs or just your own list's files or whatever you always use different functions for each request...

Only if you have a page where you load always the same XML/JSON or whatever you need only one function. In that case, modify a little the Ajax function and replace b with your special function.


The functions above are for basic use.

If you want to EXTEND the function...

Yes, you can.

I'm using a lot of APIs and one of the first functions I integrate into every HTML page is the first Ajax function in this answer, with GET only...

But you can do a lot of stuff with XMLHttpRequest 2:

I made a download manager (using ranges on both sides with resume, filereader, filesystem), various image resizers converters using canvas, populate web SQL databases with base64images and much more... But in these cases you should create a function only for that purpose... sometimes you need a blob, array buffers, you can set headers, override mimetype and there is a lot more...

But the question here is how to return an Ajax response... (I added an easy way.)


Another solution is to execute code via sequential executor nsynjs.

If underlying function is promisified

nsynjs will evaluate all promises sequentially, and put promise result into data property:

_x000D_
_x000D_
function synchronousCode() {_x000D_
_x000D_
    var getURL = function(url) {_x000D_
        return window.fetch(url).data.text().data;_x000D_
    };_x000D_
    _x000D_
    var url = 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js';_x000D_
    console.log('received bytes:',getURL(url).length);_x000D_
    _x000D_
};_x000D_
_x000D_
nsynjs.run(synchronousCode,{},function(){_x000D_
    console.log('synchronousCode done');_x000D_
});
_x000D_
<script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>
_x000D_
_x000D_
_x000D_

If underlying function is not promisified

Step 1. Wrap function with callback into nsynjs-aware wrapper (if it has promisified version, you can skip this step):

var ajaxGet = function (ctx,url) {
    var res = {};
    var ex;
    $.ajax(url)
    .done(function (data) {
        res.data = data;
    })
    .fail(function(e) {
        ex = e;
    })
    .always(function() {
        ctx.resume(ex);
    });
    return res;
};
ajaxGet.nsynjsHasCallback = true;

Step 2. Put synchronous logic into function:

function process() {
    console.log('got data:', ajaxGet(nsynjsCtx, "data/file1.json").data);
}

Step 3. Run function in synchronous manner via nsynjs:

nsynjs.run(process,this,function () {
    console.log("synchronous function finished");
});

Nsynjs will evaluate all operators and expressions step-by-step, pausing execution in case if result of some slow function is not ready.

More examples here: https://github.com/amaksr/nsynjs/tree/master/examples


After reading all the responses here and with my experiences, I would like to resume the detail of callback, promise and async/await for the asynchronous programming in JavaScript.

1) Callback : The fundamental reason for a callback is to run code in response of an event (see the example below). We use callback in JavaScript every time.

const body = document.getElementsByTagName('body')[0];
function callback() {
  console.log('Hello');
}
body.addEventListener('click', callback);

But if you must use many nested callbacks in the example below, it will be fairy terrible for the code refactoring.

asyncCallOne(function callback1() {
  asyncCallTwo(function callback2() {
    asyncCallThree(function callback3() {
        ...
    })
  })
})

2) Promise : a syntax ES6 - Promise resolves the callback hell issue !

const myFirstPromise = new Promise((resolve, reject) => {
  // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
  // In this example, we use setTimeout(...) to simulate async code. 
  // In reality, you will probably be using something like XHR request or an HTML5 API.
  setTimeout(() => {
    resolve("Success!")  // Yay! Everything went well!
  }, 250)
}) 

myFirstPromise
  .then((res) => {
    return res.json();
  })
  .then((data) => {
    console.log(data);
  })
  .catch((e) => {
    console.log(e);
  });

myFirstPromise is a Promise instance that represents the process of async codes. The resolve function signals that the Promise instance has finished. Afterwards, we can call .then() (a chain of .then as you want) and .catch() on the promise instance:

then — Runs a callback you pass to it when the promise has fulfilled.
catch — Runs a callback you pass to it when something went wrong.

3) Async/Await : a new syntax ES6 - Await is basically sugar syntax of Promise !

Async function provide us with a clean and concise syntax that enables us to write less code to accomplish the same outcome we would get with promises. Async/Await looks similar to synchronous code, and synchronous code is much easier to read and write. To catch errors with Async/Await, we can use the block try...catch. In here, you don't need to write a chain of .then() of Promise syntax.

const getExchangeRate = async () => {
  try {
    const res = await fetch('https://getExchangeRateData');
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

getExchangeRate();

Conclusion : These are totally the three syntaxs for asynchronous programming in JavaScript that you shoud well understand. So if possible, I recommend that you should use "promise" or "async/await" for refactoring your asynchronous codes (mostly for XHR requests) !


Have a look at this example:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope,$http) {

    var getJoke = function(){
        return $http.get('http://api.icndb.com/jokes/random').then(function(res){
            return res.data.value;  
        });
    }

    getJoke().then(function(res) {
        console.log(res.joke);
    });
});

As you can see getJoke is returning a resolved promise (it is resolved when returning res.data.value). So you wait until the $http.get request is completed and then console.log(res.joke) is executed (as a normal asynchronous flow).

This is the plnkr:

http://embed.plnkr.co/XlNR7HpCaIhJxskMJfSg/

ES6 way (async - await)

(function(){
  async function getJoke(){
    let response = await fetch('http://api.icndb.com/jokes/random');
    let data = await response.json();
    return data.value;
  }

  getJoke().then((joke) => {
    console.log(joke);
  });
})();

Await

Request works in ansynchronous way so you can't read data in synchronous way as typical code. However using async/await you can create async code which looks close/similar to synch code. Code which process request data needs to be wrapped by async function (load in below snippet) and inside it you need to add await keywort before foo() (which also use async/await).

_x000D_
_x000D_
async function foo() {
  var url= 'https://jsonplaceholder.typicode.com/todos/1';
  var result= await (await fetch(url)).text(); // or .json()
  return result;
}

async function load() {
  var result = await foo();
  console.log(result);
}

load();
_x000D_
_x000D_
_x000D_

Remember that async function allways wrap (in implicit way) its result into promise (so it return promise).


2017 answer: you can now do exactly what you want in every current browser and node

This is quite simple:

  • Return a Promise
  • Use the 'await', which will tell JavaScript to await the promise to be resolved into a value (like the HTTP response)
  • Add the 'async' keyword to the parent function

Here's a working version of your code:

(async function(){

var response = await superagent.get('...')
console.log(response)

})()

await is supported in all current browsers and node 8


If you're not using jQuery in your code, this answer is for you

Your code should be something along the lines of this:

function foo() {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
    return httpRequest.responseText;
}

var result = foo(); // always ends up being 'undefined'

Felix Kling did a fine job writing an answer for people using jQuery for AJAX, I've decided to provide an alternative for people who aren't.

(Note, for those using the new fetch API, Angular or promises I've added another answer below)


What you're facing

This is a short summary of "Explanation of the problem" from the other answer, if you're not sure after reading this, read that.

The A in AJAX stands for asynchronous. That means sending the request (or rather receiving the response) is taken out of the normal execution flow. In your example, .send returns immediately and the next statement, return result;, is executed before the function you passed as success callback was even called.

This means when you're returning, the listener you've defined did not execute yet, which means the value you're returning has not been defined.

Here is a simple analogy

function getFive(){ 
    var a;
    setTimeout(function(){
         a=5;
    },10);
    return a;
}

(Fiddle)

The value of a returned is undefined since the a=5 part has not executed yet. AJAX acts like this, you're returning the value before the server got the chance to tell your browser what that value is.

One possible solution to this problem is to code re-actively , telling your program what to do when the calculation completed.

function onComplete(a){ // When the code completes, do this
    alert(a);
}

function getFive(whenDone){ 
    var a;
    setTimeout(function(){
         a=5;
         whenDone(a);
    },10);
}

This is called CPS. Basically, we're passing getFive an action to perform when it completes, we're telling our code how to react when an event completes (like our AJAX call, or in this case the timeout).

Usage would be:

getFive(onComplete);

Which should alert "5" to the screen. (Fiddle).

Possible solutions

There are basically two ways how to solve this:

  1. Make the AJAX call synchronous (lets call it SJAX).
  2. Restructure your code to work properly with callbacks.

1. Synchronous AJAX - Don't do it!!

As for synchronous AJAX, don't do it! Felix's answer raises some compelling arguments about why it's a bad idea. To sum it up, it'll freeze the user's browser until the server returns the response and create a very bad user experience. Here is another short summary taken from MDN on why:

XMLHttpRequest supports both synchronous and asynchronous communications. In general, however, asynchronous requests should be preferred to synchronous requests for performance reasons.

In short, synchronous requests block the execution of code... ...this can cause serious issues...

If you have to do it, you can pass a flag: Here is how:

var request = new XMLHttpRequest();
request.open('GET', 'yourURL', false);  // `false` makes the request synchronous
request.send(null);
 
if (request.status === 200) {// That's HTTP for 'ok'
  console.log(request.responseText);
}

2. Restructure code

Let your function accept a callback. In the example code foo can be made to accept a callback. We'll be telling our code how to react when foo completes.

So:

var result = foo();
// code that depends on `result` goes here

Becomes:

foo(function(result) {
    // code that depends on `result`
});

Here we passed an anonymous function, but we could just as easily pass a reference to an existing function, making it look like:

function myHandler(result) {
    // code that depends on `result`
}
foo(myHandler);

For more details on how this sort of callback design is done, check Felix's answer.

Now, let's define foo itself to act accordingly

function foo(callback) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onload = function(){ // when the request is loaded
       callback(httpRequest.responseText);// we're calling our method
    };
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
}

(fiddle)

We have now made our foo function accept an action to run when the AJAX completes successfully, we can extend this further by checking if the response status is not 200 and acting accordingly (create a fail handler and such). Effectively solving our issue.

If you're still having a hard time understanding this read the AJAX getting started guide at MDN.


ECMAScript 6 has 'generators' which allow you to easily program in an asynchronous style.

function* myGenerator() {
    const callback = yield;
    let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
    console.log("response is:", response);

    // examples of other things you can do
    yield setTimeout(callback, 1000);
    console.log("it delayed for 1000ms");
    while (response.statusText === "error") {
        [response] = yield* anotherGenerator();
    }
}

To run the above code you do this:

const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function

If you need to target browsers that don't support ES6 you can run the code through Babel or closure-compiler to generate ECMAScript 5.

The callback ...args are wrapped in an array and destructured when you read them so that the pattern can cope with callbacks that have multiple arguments. For example with node fs:

const [err, data] = yield fs.readFile(filePath, "utf-8", callback);

The question was:

How do I return the response from an asynchronous call?

which CAN be interpreted as:

How to make asynchronous code look synchronous?

The solution will be to avoid callbacks, and use a combination of Promises and async/await.

I would like to give an example for a Ajax request.

(Although it can be written in Javascript, I prefer to write it in Python, and compile it to Javascript using Transcrypt. It will be clear enough.)

Lets first enable JQuery usage, to have $ available as S:

__pragma__ ('alias', 'S', '$')

Define a function which returns a Promise, in this case an Ajax call:

def read(url: str):
    deferred = S.Deferred()
    S.ajax({'type': "POST", 'url': url, 'data': { },
        'success': lambda d: deferred.resolve(d),
        'error': lambda e: deferred.reject(e)
    })
    return deferred.promise()

Use the asynchronous code as if it were synchronous:

async def readALot():
    try:
        result1 = await read("url_1")
        result2 = await read("url_2")
    except Exception:
        console.warn("Reading a lot failed")

Using ES2017 you should have this as the function declaration

async function foo() {
    var response = await $.ajax({url: '...'})
    return response;
}

And executing it like this.

(async function() {
    try {
        var result = await foo()
        console.log(result)
    } catch (e) {}
})()

Or the Promise syntax

foo().then(response => {
    console.log(response)

}).catch(error => {
    console.log(error)

})

You are using Ajax incorrectly. The idea is not to have it return anything, but instead hand off the data to something called a callback function, which handles the data.

That is:

function handleData( responseData ) {

    // Do what you want with the data
    console.log(responseData);
}

$.ajax({
    url: "hi.php",
    ...
    success: function ( data, status, XHR ) {
        handleData(data);
    }
});

Returning anything in the submit handler will not do anything. You must instead either hand off the data, or do what you want with it directly inside the success function.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to ajax

Getting all files in directory with ajax Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource Fetch API request timeout? How do I post form data with fetch api? Ajax LARAVEL 419 POST error Laravel 5.5 ajax call 419 (unknown status) How to allow CORS in react.js? Angular 2: How to access an HTTP response body? How to post a file from a form with Axios

Examples related to asynchronous

How to read file with async/await properly? Use Async/Await with Axios in React.js Waiting until the task finishes How to reject in async/await syntax? React - Display loading screen while DOM is rendering? angular 2 how to return data from subscribe How do I access store state in React Redux? SyntaxError: Unexpected token function - Async Await Nodejs Why does .json() return a promise? Why is setState in reactjs Async instead of Sync?