【问题标题】:async/await not working properly with fs.writeFileasync/await 无法与 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?
}

【问题讨论】:

    标签: node.js asynchronous async-await fs


    【解决方案1】:

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

    await yourFunction(...);
    

    async 不是这样的

    async yourFunction();
    

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

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

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

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

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

    1. 您导入 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);
         }
       }
      
    2. 您导入 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
    猜你喜欢
    • 2020-08-21
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 2017-10-24
    • 2019-07-15
    • 1970-01-01
    相关资源
    最近更新 更多