异步等待嵌套时如何工作?

时间:2019-11-13 17:16:44

标签: javascript node.js promise async-await

编辑:根据回复,我更新了示例和回复。

我真的很难理解异步并等待。当我感觉自己了解了这一点时,它就不起作用了。我相信以下内容对于大多数人来说都是显而易见的,但是似乎有一个清晰的概念我没能把握。我已经尝试阅读指南和教程,但是这种理解仍然在逃避我。

我正在使用的代码是节点js,并使用express接收HTTP请求。收到HTTP请求后,它将调用服务,该服务将调用数据库服务,而数据库服务又将调用MSSQL节点库。

为了简单地演示这一点,我创建了一个小样本JS文件。

async function getData() {

  var serviceData = await serviceGetData();
  console.log('response ' + serviceData.message);
}

async function serviceGetData() {
  var databaseData = await databaseGetData();
  return databaseData;
}

async function databaseGetData() {
  var libraryData = await libraryGetData();
  return libraryData; // i also tried just libraryData

}

function libraryGetData() {
  return new Promise((reject, resolve) => {
    setTimeout(function() {
      var object = { message: 'Hello World' };
      resolve(object);
    }, 1000);
  });
}
getData();

我的想法是,它将遍历函数,到达await,调用库函数,等待响应,然后一直返回链并输出到控制台。

您可能会说,这不会发生。它确实返回了链,但输出:

(node:4688) UnhandledPromiseRejectionWarning: #<Object>
(node:4688) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:4688) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我发现这很奇怪,因为我认为它会在等待中等待,然后遍历消息。我也感到奇怪的是serviceData是一个承诺?这意味着我必须一直将承诺链式链接起来,但是我认为异步/等待的整个重点是不再需要链接式链接。

有人可以指出我正确的方向吗?

1 个答案:

答案 0 :(得分:2)

关于异步/等待,有一件重要的事情要理解:异步函数总是返回一个Promise。!如果async函数返回常数值,则promise将同步解析,但是您仍然需要将其视为promise。

这意味着在这里:var databaseData = databaseGetData();您将databaseData设置为 promise ,因为databaseGetData()是一个异步函数。您需要等待诺言,这意味着serviceGetData()实际上也应该是异步的,这意味着getData()也必须是异步的。这揭示了async / await的重要原理:如果一个函数将在其调用链的任何位置执行任何异步操作,则该函数不可避免地将需要处理一个promise-无法解决,您无法将异步结果带入一个同步上下文。

根据问题更新进行编辑:您还收到了未兑现的承诺拒绝,因为您在resolve中交换了rejectnew Promise((reject, resolve) => {的顺序-因此,当您致电{ {1}}实际上是在拒绝您的承诺,并以resolve(object)作为错误消息。