异步等待正确使用
Posted
技术标签:
【中文标题】异步等待正确使用【英文标题】:Async await correct usage 【发布时间】:2020-09-10 21:19:26 【问题描述】:我已经阅读了一些关于 async/await 的文档,并尝试通过一个示例来更好地理解它。我所期待的是,下面没有 async 和 await 的代码将首先打印字符串“Completed”,然后是文件的内容。但即使在添加了 async 和 await 之后,我也看到打印顺序没有受到影响。我的印象是异步的,在这种情况下等待使用将首先打印文件内容,然后是字符串“已完成”。
var fs = require('fs');
getTcUserIdFromEmail();
async function getTcUserIdFromEmail( tcUserEmail )
let userInfo = ;
let userFound = false;
// Read the file that is containing the information about the active users in Teamcenter.
await fs.readFile('tc_user_list.txt', function(err, data)
if( err )
console.log( err );
else
console.log( data.toString() );
);
console.log( 'Completed method');
请你指出我做错了什么。
谢谢, 帕万。
【问题讨论】:
你认为await
是做什么的?你为什么要把它和回调混在一起?
fs.readFile()
不返回承诺。 Using filesystem in node.js with async / await
await
只有在等待承诺时才会做任何有用的事情。 fs.readFile()
的常规版本不返回承诺,因此等待它没有任何用处。您可以使用fs.promises.readFile()
,它将返回一个承诺并且不接受回调。结果来自等待的承诺,而不是通过回调。
@GuyIncognito 它使用 fs.promises 工作,如另一个线程中所述。谢谢。
fs.promises.readFile()
不接受回调。看the documentation。结果或错误会在 Promise 中返回,而不是在回调中。如果你向它传递一个回调,该回调将永远不会被调用。当您使用 Promise 进行编程时,您会在 Promise 中返回您的结果或错误。当你等待一个承诺时,你会得到const data = await fs.promises.readFile(someFile)
的结果,你会用try/catch
捕获错误。
【参考方案1】:
await
仅在等待的表达式返回 Promise 时才有效。 fs.readFile
不返回承诺,所以现在你的 await
不做任何事情。
对我们来说幸运的是,node 提供了一个函数 fs.promises.readFile
,它类似于 fs.readFile
,但不是期待回调,而是返回一个 Promise。
const fs = require('fs')
现在你可以await fs.promises.readFile(...)
getTcUserIdFromEmail(); // > contents_of_tc_user_list
// Completed method
async function getTcUserIdFromEmail( tcUserEmail )
let userInfo = ;
let userFound = false;
const data = await fs.promises.readFile('tc_user_list.txt')
console.log(data.toString())
console.log( 'Completed method');
【讨论】:
当fs.promises.readFile()
已经存在时,无需承诺fs.readFile()
。此外,您需要表明调用getTcUserIdFromEmail()
本身需要使用await
或.then()
才能知道它何时完成,因为它也返回一个promise。
@jfriend00 请原谅我,但据我了解,对于每个异步方法,异步方法的调用者都应该“等待”它。这是因为没有回调。这种理解是否正确。
如果您只想查看日志消息,则不必等待getTcUserIdFromEmail()
。当所有异步内容解决时,您的节点进程将退出。但是,如果您想使用getTcUserIdFromEmail()
的返回值,您绝对必须等待,但是
@jfriend00 我不知道fs.promises
,我会更新我的答案以使用它,谢谢!
@PavanDittakavi - 如果您想知道返回承诺的异步函数何时完成或是否有错误,您必须使用 await
和 try/catch
或 .then()
和/或.catch()
。以上是关于异步等待正确使用的主要内容,如果未能解决你的问题,请参考以下文章
等待 dispatch_semaphore 以等待许多异步任务完成的正确方法
通过节点的异步/等待不需要按预期顺序返回结果 - 使用啥正确模式?
将 HttpContext.Current.User 与异步等待一起使用的正确方法