【问题标题】:Async function does not work with Await异步功能不适用于 Await
【发布时间】:2017-08-24 14:55:56
【问题描述】:

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

根据这个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;
      } 
  });
}

【问题讨论】:

  • 据我所知,您需要返回一个 Promise 才能使 async/await 正常运行。这段代码没有这样做。
  • ^^^ 在你的 getValue 方法中在 $.ajax 前面加上一个 return。
  • @Taplar 你能用你的方法添加答案吗
  • @tadman 你能用你的方法添加答案吗
  • 并不是说你必须用async关键字标记函数才能在里面使用await。我的意思是你作为成功回调传递的那个。

标签: javascript jquery ajax asynchronous async-await


【解决方案1】:

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

以下代码应该可以正常工作,但请注意:

  1. 所有请求都使用Promise.all同时处理,因此当它们全部解决后,会将结果记录在控制台中
  2. 我使用了 letconst 关键字,因为我假设您使用的是最新版本的 JavaScript

您可能需要查看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();

【讨论】:

  • 为什么objects[]中有两组值?
  • 如 cmets 中所述,这仅用于演示。您实际上可以复制/粘贴此代码以直接对其进行测试,但删除“object = [...]”部分供您自己使用。
猜你喜欢
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
相关资源
最近更新 更多