user7933742
user7933742

Reputation:

Async function does not work with Await

I have the following set up where my main() function makes an AJAX call and calls getValue1() and getValue2() inside SUCCESS. I am learning how to use the keywords async and await

According to this SO post and this developer manual, the following code should work. However, it doesn't. Can someone tell me why?

async function main() {
  $.ajax({
      url: "...", 
      success: function (object) {
          var html = '';
          for (var i = 0; i < object.length; i++) {
              var value1 = await getValue1(object[i].value1);
              html += '<p>' + value1 + '</p>';

              var value2 = await getValue2(object[i].value2);
              html += '<p>' + value2 + '</p>';

              console.log(html);
          }
      }
  });
}

function getValue1(value1) {
  $.ajax({
      url: "...", 
      success: function (value1) {
          return value1;
      } 
  });
}

function getValue2(value2) {
  $.ajax({
      url: "...", 
      success: function (value2) {
          return value2;
      } 
  });
}

Upvotes: 0

Views: 500

Answers (1)

Jonathan
Jonathan

Reputation: 792

Firstly you need to put the async keyword in the same function where await is. And for this to work, you need to return Promise in your getValue1/2 functions.

The following code should work as it is, but note that:

  1. all requests are processed simultaneously using Promise.all, so when they are all resolved it will log the result in console
  2. I used let and const keywords, as I assumed that you use a recent version of JavaScript

You may need to take a look at the Promise's documentation to fully understand the code below.

function main() {
  $.ajax({
    url: 'https://api.ipify.org',
    success: function (object) {
      // this is for demonstration only:
      object = [
        {
          value1: 'https://api.ipify.org',
          value2: 'https://api.ipify.org',
        },
        {
          value1: 'https://api.ipify.org',
          value2: 'https://api.ipify.org',
        },
      ];
      // ^^^ remove this for your use

      // for some reasons, async callback in success won't work with jQuery
      // but using this self-calling async function will do the job
      (async function () {
        const requests = [];
        for (let i = 0; i < object.length; i++) {
          requests.push(getValue1(object[i].value1));
          requests.push(getValue2(object[i].value2));
        }

        // all requests are done simultaneously
        const results = await Promise.all(requests);

        // will print ["<your ip>", "<your ip>", ...]
        console.log(results);
      })();
    },
  });
}

function getValue1(param1) {
  // return a promise that resolve when request is done
  return new Promise(function (resolve, reject) {
    $.ajax({
      url: param1,
      success: resolve,
      error: reject,
    });
  });
}

function getValue2(param2) {
  // return a promise that resolve when request is done
  return new Promise(function (resolve, reject) {
    $.ajax({
      url: param2,
      success: resolve,
      error: reject,
    });
  });
}

// call main for testing
main();

Upvotes: 2

Related Questions