【问题标题】:Returning a value after writing to a file is complete写入文件完成后返回值
【发布时间】:2017-11-21 21:23:46
【问题描述】:

您好,我正在 Node JS 中编写一个函数,我必须为其返回一个文件路径。我的问题出在我正在写入文件的那个函数中,我希望在写入文件完成后,我的返回应该可以工作。在查看代码之前,我知道这可能是重复的,并且我确实对此进行了研究,但我不仅能够到达那里。我试过使用回调,但问题是我想返回一个已经定义的值。因此,在做出任何重复或缺乏研究的判断之前,请阅读代码。

另外,尝试在 fs.append 回调中返回值,但仍然没有解决。

我的功能:

const fs = require('fs');
const path = require('path');

module.exports.createDownloadFile = (request) => {
  let filePath;
  if (request) {
    const userID = xyz;
    filePath = path.join(__dirname, userID.concat('.txt'));
    fs.open(filePath, 'w', (err) => {
      if (err) throw new Error('FILE_NOT_PRESENT');
      fs.appendFile(filePath, 'content to write');
    });
  }

  return filePath;
};

我正在获取我正在调用函数的文件路径,只是那个时候文件是空的,这就是为什么我想在文件完全写入后返回。

【问题讨论】:

    标签: javascript node.js promise


    【解决方案1】:

    Promises 允许您像传统同步代码一样构造代码和返回值。 util.promisify 可以帮助 promisify 常规节点回调函数。

    const fs = require('fs')
    const path = require('path')
    const fsAppendFileAsync = util.promisify(fs.appendFile)
    const fsOpenAsync = util.promisify(fs.open)
    
    module.exports.createDownloadFile = async (request) => {
      if (!request) throw new Error('nope')
      const userID = xyz
      let filePath = path.join(__dirname, userID.concat('.txt'))
      let fd = await fsOpenAsync(filePath, 'w')
      await fsAppendFileAsync(fd, 'content to write')
      return filePath
    };
    

    请注意,async/await 是 ES2017,需要 Node.js 7.6+Babel

    使用w 打开文件会创建或截断文件,并且 promise 会拒绝抛出的错误,因此我将错误处理程序排除在外。您可以使用try {} catch (e) {} 块来处理特定错误。

    Bluebird 承诺库也很有帮助,尤其是 Promise.promisifyAll,它为您创建了承诺的 Async 方法:

    const Promise = require('bluebird')
    const fs = Promise.promisifyAll(require('fs'))
    fs.appendFileAsync('file', 'content to write')
    

    【讨论】:

      【解决方案2】:

      使用这样的承诺:

      const fs = require('fs');
      const path = require('path');
      
      module.exports.createDownloadFile = (request) => {
          return new Promise((resolve, reject) => {
              let filePath;
              if (request) {
                  const userID = xyz;
                  filePath = path.join(__dirname, userID.concat('.txt'));
                  fs.open(filePath, 'w', (err) => {
                      if (err) reject(err);
                      else
                          fs.appendFile(filePath, 'content to write', (err) => {
                              if (err) 
                                  reject(err)
                              else
                              resolve(filePath)
                          });
                  });
              }
          });
      };
      

      然后这样称呼它:

      createDownloadFile(requeset).then(filePath => {
          console.log(filePath)
      })
      

      或者使用没有 Promises 的同步函数:

      module.exports.createDownloadFile = (request) => {
              let filePath;
              if (request) {
                  const userID = xyz;
                  filePath = path.join(__dirname, userID.concat('.txt'));
                  fs.openSync(filePath,"w");
                  fs.appendFileSync(filePath, 'content to write');
              }
              return filePath;
      };
      

      【讨论】:

      • 没错,我只是忘了提,我已经尝试过 Promises。不使用promise还有其他方法吗?
      猜你喜欢
      • 1970-01-01
      • 2018-06-21
      • 1970-01-01
      • 2011-06-17
      • 2018-10-18
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多