编辑:根据回复,我更新了示例和回复。
我真的很难理解异步并等待。当我感觉自己了解了这一点时,它就不起作用了。我相信以下内容对于大多数人来说都是显而易见的,但是似乎有一个清晰的概念我没能把握。我已经尝试阅读指南和教程,但是这种理解仍然在逃避我。
我正在使用的代码是节点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是一个承诺?这意味着我必须一直将承诺链式链接起来,但是我认为异步/等待的整个重点是不再需要链接式链接。
有人可以指出我正确的方向吗?
答案 0 :(得分:2)
关于异步/等待,有一件重要的事情要理解:异步函数总是返回一个Promise。!如果async函数返回常数值,则promise将同步解析,但是您仍然需要将其视为promise。
这意味着在这里:var databaseData = databaseGetData();
您将databaseData
设置为 promise ,因为databaseGetData()
是一个异步函数。您需要等待诺言,这意味着serviceGetData()
实际上也应该是异步的,这意味着getData()
也必须是异步的。这揭示了async / await的重要原理:如果一个函数将在其调用链的任何位置执行任何异步操作,则该函数不可避免地将需要处理一个promise-无法解决,您无法将异步结果带入一个同步上下文。
根据问题更新进行编辑:您还收到了未兑现的承诺拒绝,因为您在resolve
中交换了reject
和new Promise((reject, resolve) => {
的顺序-因此,当您致电{ {1}}实际上是在拒绝您的承诺,并以resolve(object)
作为错误消息。