【问题标题】: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捕获错误。

标签: node.js async-await


【解决方案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 - 如果您想知道返回承诺的异步函数何时完成或是否有错误,您必须使用 awaittry/catch.then()和/或.catch()
猜你喜欢
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
相关资源
最近更新 更多