异步与标准回调混合

Async mixed with standard callback

我刚开始在 Javascript 学习 Promises,碰巧 async/await

在我的理解中,如果我指定一个函数,async,javascript 将始终包装我的函数的内容,return 一个 Promise 而不是不管我在 returning.

让我们假设以下场景:

async function httpRequest() {
   oReq = new XMLHttpRequest();
   oReq.addEventListener("load", function() {
      return this.responseText;
   });

   oReq.open("GET", "http://some.url.here");
   oReq.send();
}

httpRequest().then(function(httpResult) {
    console.log(httpResult);
}); 

我的假设是否正确,上面的情况不会起作用,因为 httpRequest() 不是 return 任何东西,XMLHttpRequest return 的回调是什么只有,因此我的结果很可能是 undefined?

如果是,我如何才能修复 httpRequest() 使其在 async/await 场景中工作?

基本上,您正在尝试编写一个 async 函数,而该函数中没有任何等待。当代码中存在一些异步性时,您使用 async/await,而在您的代码中则没有。

这是一个可能有用的示例:

const getItemsAsync = async () => {
    const res = await DoSomethingAsync();
    return res.items;
}

const items = await getItemsAsync();

如您所见,DoSomethingAsync 是我等待结果的异步函数,即 res。那时,代码将暂停。一旦 promise 得到解决,代码将恢复,因此将 return res.items,这意味着 items 实际上将包含异步函数的结果。

此外,async/await 只是一种空间语法,通过赋予代码更同步的形式(而非实质),使代码更具可读性。

如果您真的想让它异步,您可以承诺您的同步代码,以使其 return 承诺等待,然后将被解决或拒绝。

你这里有一个执行异步操作的异步函数,其中该操作使用承诺。这意味着您需要设置一个函数来显式管理和 returns 一个承诺。您在这里不需要 async 关键字,因为您想明确地 return 您创建的 Promise,而不是 async 关键字为您创建的承诺(您不能直接管理)。

function httpRequest() {

   // Return a promise (this is what an async function does for you)
   return new Promise(resolve => {
     const oReq = new XMLHttpRequest();
     oReq.addEventListener("load", function() {

        // Resolve the promise when the async operation is complete.
        resolve(this.responseText);
     });

     oReq.open("GET", "http://some.url.here");
     oReq.send();
   };
}

现在函数明确地 returns 一个承诺,它可以像 async 函数一样被 awaited。或者像任何承诺一样与 then() 一起使用。

async function someFunction() {
  // await
  const awaitedResponse = await httpRequest();
  console.log(awaitedResponse);

  // or promise chain
  httpRequest().then(responseText => console.log(responseText));
};