异步功能不适用于等待

时间:2017-08-24 14:55:56

标签: javascript jquery ajax asynchronous async-await

我有以下设置:main()函数进行AJAX调用,并在SUCCESS内调用getValue1()getValue2()。我正在学习如何使用关键字 async 等待

根据此SO post和此开发人员manual,以下代码应该有效。但是,它没有。有人可以告诉我为什么吗?

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

1 个答案:

答案 0 :(得分:2)

首先,您需要将async关键字放在await所在的同一个函数中。为此,您需要在Promise函数中返回getValue1/2

以下代码应该按原样运行,但请注意:

  1. 使用Promise.all同时处理所有请求,因此当它们全部解析后,它会将结果记录在控制台中
  2. 我使用了letconst个关键字,因为我认为您使用的是最新版本的JavaScript
  3. 您可能需要查看Promise's documentation以完全理解以下代码。

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