async/await 无法与 fs.writeFile 一起正常工作

Posted

技术标签:

【中文标题】async/await 无法与 fs.writeFile 一起正常工作【英文标题】:async/await not working properly with fs.writeFile 【发布时间】:2021-06-30 20:52:10 【问题描述】:

我将一个回调传递给 fs.writeStream,由于某种原因,它之后的任何任务都将首先被调用,然后再执行回调。


async function writeFile(file, callBack) 
    // awaiting this also doesn't work
  fs.writeFile(arg1, arg2, arg3, (error) => callBack(error)) 



async function task() 
  let count = 0;

  const callBack = (error) => 
    if (error) 
      count--;
     else 
      count++;
    
  

  for(const file of files)  // files.length = 1
    await writeFile(file, callBack);  
  
  
  console.log(count) // Prints 0, should be 1. Why does this get called before the callback?

【问题讨论】:

【参考方案1】:

首先,你说错了。如果你想等待一个异步函数,你必须像这样用await调用它

await yourFunction(...);

async 不是这样的

async yourFunction();

其次,您显然将async 函数和函数与回调混合在一起。即,当你有

async function yourFunction() 
  anotherFunction((error, data) =>  
     ... 
  );

您实际上返回的是一个Promise<void>,它会立即解决。 async函数不等待任何基于回调函数的回调。

第三,你没有使用writeFile(file, callBack)函数的file参数,而是三个完全未定义的参数arg1, arg2, arg3

对于你目前的问题,有两种可能

    您导入 fs 模块的 promise 函数并正确使用它们(从 Node v10 开始可用)

     const fsp = require("fs").promises;
    
     async function writeFile(filename, data, errorHandler) 
       try
         await fsp.writeFile(filename, data);
        catch (e) 
         errorHandler(e);
       
     
    

    您导入 fs 模块的经典回调形式并将函数包装到一个 Promise 中

     const fs = require("fs");
    
     async function writeFile(filename, data, errorHandler) 
       return new Promise((resolve, reject) => 
         fs.writeFile(filename, data, (e) => 
           if (e) 
             errorHandler(e);
             // if you want to continue and adjust the count 
             // even if the writeFile failed
             // you don't need the reject here
             return reject(e);
           
           resolve();
         );
       );
     
    

【讨论】:

async 是发布此内容时的拼写错误 - 应该是 await。我也尝试等待fs.writeFile,但没有成功。会尝试你的建议! await fs.writeFile 什么“不起作用”?有错误信息吗?你导入了 fs-module 的 promise-form 了吗?【参考方案2】:

假设您导入了正确的 fs 库,即fs/promises,您的答案应该如下所示:

async function writeFile(file) 
  await fs.writeFile(file);


async function task() 
  let count = 0;

  const callBack = (error) => 
    if (error) 
      count--;
     else 
      count++;
    
  

  for(const file of files)  // files.length = 1
    await writeFile(file);  
  
  
  console.log(count) // Prints 0, should be 1. Why does this get called before the callback?

您缺少实际等待 fsPromises.writeFile 的异步结果所需的 await,如您在此处看到的:https://nodejs.org/dist/latest-v15.x/docs/api/fs.html#fs_fspromises_writefile_file_data_options 此外,如果您使用基于承诺的 fs,您将不需要也不需要回调 (ftfy)

如果你还想数,可以这样操作:

async function writeFile(file) 
  await fs.writeFile(file);


async function task() 
  let count = 0;

  for (const file of files)  // files.length = 1
    try 
      await writeFile(file);
      count++; // <-------- NOTICE THIS PART HERE
     catch (e) 
      count--;
    
  
  
  console.log(count) // Prints 0, should be 1. Why does this get called before the callback?

【讨论】:

相当过时,但是是的。解决了这个问题。 ty

以上是关于async/await 无法与 fs.writeFile 一起正常工作的主要内容,如果未能解决你的问题,请参考以下文章

node.js async/await 与 MySQL 一起使用

如何在 Swift 5.5 中将 async/await 与 SwiftUI 一起使用?

Rollup 无法转译 async/await - regeneratorRuntime 未定义

.save() 无法使用 async/await 正确保存到 mongoDB

无法理解 async/await nodejs

promise与async和await的区别