简体   繁体   English

async await 在嵌套时如何工作?

[英]async await how does it work when nesting?

edit: based on responses I've updated my example and response.编辑:根据回复,我更新了我的示例和回复。

I'm really struggling to understand async and await.我真的很难理解异步和等待。 The moment I feel like I am understanding it, it then doesn't work how i would expect.当我觉得我理解它的那一刻,它就不会像我期望的那样工作。 I'm sure the below is pretty obvious to most people, but there seems to be a clear concept that i failing to grasp.我相信下面的内容对大多数人来说是很明显的,但似乎有一个我没有掌握的明确概念。 I've tried reading guides and tutorials but the understanding is still escaping me.我试过阅读指南和教程,但理解仍然是 escaping 我。

The code I'm working is node js and uses express to receive HTTP requests.我正在使用的代码是 node js 并使用 express 来接收 HTTP 请求。 When the HTTP request is received, it calls a service, and this service calls a database service which in turn calls the MSSQL node library.当收到 HTTP 请求时,它调用一个服务,该服务调用一个数据库服务,该数据库服务又调用 MSSQL 节点库。

To demonstrate this in a simple way, i created a small sample JS file.为了以简单的方式演示这一点,我创建了一个小的示例 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();

My thought is, it would traverse through the functions, get to the await, call the library function, wait for the response and then come all the way back up the chain and output to console.我的想法是,它会遍历函数,到达等待,调用库 function,等待响应,然后一路返回链和 output 到控制台。

As you probably can tell, this isn't what happens.正如您可能知道的那样,这不是发生的事情。 It does come back up the chain, but instead it outputs:它确实回到了链上,但它输出:

(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.

I find this strange, because I thought it would wait at the await, and then traverse back up with the message.我觉得这很奇怪,因为我认为它会在 await 处等待,然后带着消息遍历回来。 I also find it strange that serviceData is a promise?我也觉得很奇怪 serviceData 是 promise? This implies i have to chain the promise all the way up, but I thought the whole point of async / await was not to need to chain any more.这意味着我必须一直链接 promise,但我认为 async / await 的全部意义在于不再需要链接。

Can someone point me in the right direction please?有人可以指出我正确的方向吗?

There's one important thing to understand about async/await: An async function always returns a Promise.关于异步/等待有一件重要的事情需要了解:异步 function 总是返回 Promise。 Without exception, The promise will resolve synchronously if the async function returns a constant value.无一例外,如果异步 function 返回一个常数值,promise 将同步解析。 but you still need to treat it as a promise.但是您仍然需要将其视为承诺。

This means right here: var databaseData = databaseGetData();这意味着在这里: var databaseData = databaseGetData(); you are setting databaseData to a promise, because databaseGetData() is an async function.您将databaseData设置为 promise,因为databaseGetData()是异步 function。 You need to await the promise, which means, indeed, serviceGetData() also should be async, which means, yep, getData() also needs to be.您需要等待 promise,这实际上意味着serviceGetData()也应该是异步的,这意味着,是的, getData()也需要是。 This reveals an important principle of async/await: if a function will do any asynchronous action anywhere down its calling chain, that function inevitably will need to handle a promise - there's no way around that, you can't bring asynchronous results up into a synchronous context.这揭示了异步/等待的一个重要原则:如果 function 将在其调用链中的任何位置执行任何异步操作,则 function 不可避免地需要处理 ZB321DE3BDC299EC807E68385D7D9DEEB 异步方式同步上下文。

Edit in response to question update: You're also getting an uncaught promise rejection because you've swapped the order of resolve and reject in new Promise((reject, resolve) => { - thus when you call resolve(object) you're actually rejecting that promise with object as the error message.针对问题更新进行编辑:您还将收到未捕获的 promise 拒绝,因为您已在new Promise((reject, resolve) => {中交换了resolvereject的顺序 - 因此,当您调用resolve(object)时,您'重新实际拒绝 promise 与object作为错误消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM