首页 > 解决方案 > Async/Await 不等待前一个函数完成

问题描述

我正在构建一个需要多次查询我的数据库的网络应用程序,每次都从第一个数据库调用中获取数据以进行下一次调用。既然如此,我需要等到上一个通话完成后再继续。async/await 不是正确的方法吗?如果是这样,我在这里错过了什么?

var firstCall = new XMLHttpRequest();
var firstCallData;
async function sendFirstCall() {
  firstCall.open('GET', queryURL);
  firstCall.onload = function() {
    firstCallData = JSON.parse(firstCall.responseText);
  };
  firstCall.send();
};

async function logData() {
  await sendFirstCall();
  console.log(firstCallData);
}

logData();

我对 JS 并不完全陌生,但我不经常写它,而且我绝对不熟悉 async/await 的工作原理。任何帮助表示赞赏!

标签: javascriptajaxasync-await

解决方案


sendFirstCall函数没有返回 a Promise(无论如何也不是特别有意义的),所以没有什么 to await. 我不知道是否XMLHttpRequest有任何现代Promise功能(像fetchAxios 或 Axios 之类的工具,您可能会考虑研究这些功能),但您可以将其包装在Promise. 也许是这样的:

function sendFirstCall() {
  return new Promise(function(resolve, reject) {
    firstCall.open('GET', queryURL);
    firstCall.onload = function() {
      firstCallData = JSON.parse(firstCall.responseText);
      resolve();
    };
    firstCall.send();
  });
}

请注意,我还async从函数定义中删除了 。这里并没有真正使用 async/await,只是手动返回 a Promise(它本身是可等待的,因此消费代码仍然可以使用await)。


或者,也许更习惯地说,它Promise本身可以解析为数据:

function sendFirstCall() {
  return new Promise(function(resolve, reject) {
    firstCall.open('GET', queryURL);
    firstCall.onload = function() {
      resolve(JSON.parse(firstCall.responseText));
    };
    firstCall.send();
  });
}

那么消费代码将是:

firstCallData = await sendFirstCall();

这样操作本身就没有副作用,它只是(异步)产生一个值,而消费代码决定如何处理该值。


如果失败或导致错误代码,您还可以使用reject回调中的回调Promise来处理错误。XMLHttpRequest否则,失败/错误只会丢失,Promise永远不会解决或拒绝。


推荐阅读