【问题标题】:Ajax and async awaitAjax 和异步等待
【发布时间】:2018-11-29 19:19:34
【问题描述】:

我有点困惑为什么我的 ajax 调用没有返回结果。我认为定义为异步的方法会自动返回一个承诺。我做错了什么?

async AjaxCall(filePath) {
      let xhttp = new XMLHttpRequest();

      xhttp.open('POST', filePath, true);
      xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
      xhttp.send();

     xhttp.onreadystatechange = function() {
          if (xhttp.readyState === 4 && xhttp.status === 200) {
            return xhttp.responseText;
          }
      }
  }


async function Test() {
  var result = await AjaxCall("file.php");
  alert(result);
}

Test();

【问题讨论】:

标签: javascript ajax async-await


【解决方案1】:

async/await 是(非常有用的)用于创建和使用 Promise 的语法糖。你的 AjaxCall 函数隐式地创建了一个承诺,但随后也隐式地立即用值 undefined 解析它,因为你从来没有 await 任何东西,唯一的 return 不是直接在 AjaxCall 中,而是在onreadystatechange 回调。

可以围绕 XHR 包装承诺,但您不必:fetch 已经这样做了:

async function Test() {
  var result = await fetch("file.php");
  if (result.ok) {
      alert(await result.text());
   }
}

但如果你想自己做,你需要显式地创建和使用一个 Promise,而不是在 AjaxCall 上使用 async

function AjaxCall(filePath) {
    return new Promise((resolve, reject) => {
        let xhttp = new XMLHttpRequest();

        xhttp.open('POST', filePath, true);
        xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhttp.send();

        xhttp.onreadystatechange = function() {
            if (xhttp.readyState === 4) {
                if (xhttp.status === 200) {
                    resolve(xhttp.responseText);
                } else {
                    reject(); // Probably including some rejection reason
                }
            }
        };
    });
}

【讨论】:

  • 哇,这是一个很好的答案。我什至学到了一些新东西。从未听说过“获取”。
【解决方案2】:

问题在于您实际上并没有从函数中返回任何数据。您正在 onreadystatechange 函数中返回数据,但这只是丢失并且从未使用过。具体看一下here这段代码:

function makeRequest(method, url) {
    return new Promise(function (resolve, reject) {
        let xhr = new XMLHttpRequest();
        xhr.open(method, url);
        xhr.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                resolve(xhr.response);
            } else {
                reject({
                    status: this.status,
                    statusText: xhr.statusText
                });
            }
        };
        xhr.onerror = function () {
            reject({
                status: this.status,
                statusText: xhr.statusText
            });
        };
        xhr.send();
    });
}

您会注意到它已将整个函数包装在一个 Promise 中,然后您可以在调用它时使用标准的 async/await 功能。 Async/Await 实际上只是对现有 Promise 功能的封装。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 2017-04-17
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 2023-03-12
    • 2016-07-07
    相关资源
    最近更新 更多