【问题标题】:Await promisified fs.writeFile vs fs.writeFileSync等待承诺的 fs.writeFile 与 fs.writeFileSync
【发布时间】:2019-04-19 15:08:09
【问题描述】:

其中一个选项有什么优点吗?

1.

const fs = require('fs')

const testFunc1 = async () => {
  fs.writeFileSync('text.txt', 'hello world')
}

2.

const fs = require('fs')
const util = require('util')
const writeFilePromisified = util.promisify(fs.writeFile)

const testFunc2 = async () => {
  await writeFilePromisified('text.txt', 'hello world')
}

我知道 writeFile 和 writeFileSync 之间的区别。问题是返回 testFunc1 和 testFunc2 的 Promise 之间是否存在一些差异。所以打电话是一样的吗 testFunc1.then(...) // 或等待 testFunc1 要么 testFunc2.then(...) // 或者等待 testFunc2

当文件写入完成时,这两个承诺都将得到满足。

【问题讨论】:

    标签: node.js promise


    【解决方案1】:
    fs.writeFileSync( file, data, options )
    
    fs.writeFile( file, data, options, callback)
    

    异步函数最后一个回调函数 表示异步函数完成的参数。

    The ‘fs’ module implements the File I/O operation. Methods in the fs module can be synchronous as well as asynchronous. 
    

    开发人员更喜欢异步方法而不是同步方法,因为他们在程序执行期间从不阻塞程序,而后者会阻塞。在 Node.js 中阻塞主线程是“ma​​lpractice”,因此同步函数只能用于“debugging”或没有其他选项可用时。

    fs.writeFileSync() 是一种同步方法,如果出现则创建一个新文件 指定的文件不存在,而 fs.writeFile() 是 异步方法。

    【讨论】:

      【解决方案2】:

      fs 已经包含不需要promisifypromisified API

      const fsPromises = require("fs/promises");
      await fsPromises.writeFile(file, data[, options])
      

      基于 Promise 的异步版本需要将其用作基于 Promise 的控制流的一部分,而同步版本不强制此要求。

      异步 ​​readFile/writeFile 是非阻塞的,而同步 readFileSync/writeFileSync 是阻塞的,但可以更快地完成作业。这在密集的 IO 操作期间可能会很明显。

      【讨论】:

      • fs.promise API 对于节点 10 是实验性的。
      • 请您解释一下返回 testFunc1 和 testFunc2 的两个 Promises 之间的区别。我可以看到那里没有差异。
      • testFunc1() 没用。它不会从承诺中受益。它阻塞了主线程,因为writeFileSync 是同步的。如果得到的承诺是awaited,则提供一个微小的延迟。
      【解决方案3】:

      writeFile() 和 writeFileSync() 之间的区别正如其他 writeFileSync() “阻塞”所解释的那样。那么,“阻塞”和“不阻塞”有什么区别呢?

      我写了一个小测试,比较了 writeFile() 和 writeFileSync() 的速度。我测量了 writeFileSync() 返回结果所用的时间与从调用 writeFile() 到调用其回调参数所用的时间。令我(最初)惊讶的是,两者之间没有明显的区别。 writeFile() 似乎并不比 writeFileSync() 快。那么,当它似乎使我的程序流程复杂化时,我为什么要使用它呢?

      但是,如果我不等待它的回调参数被调用,我测量了 writeFile() 所花费的时间。速度有很大差异,可能是 10 倍。

      因此差别很大或没有差别取决于程序的其余部分。如果您对 writeFileSync() 的调用需要很长时间,那么您的程序在等待 writeFileSync() 返回时将无能为力。如果您执行 writeFile() 并在执行其他任何操作之前等待回调完成,则结果没有什么不同。但是如果你不(不需要)等待它的回调被调用,writeFile() 会快得多。

      如果您编写某种调用 writeFileSync() 的服务器,这将有很大的不同。服务器在等待 writeFileSync() 完成时无法为任何新请求提供服务。如果大多数请求导致调用 writeFileSync(),这可能会对您的服务器性能产生重大影响。

      【讨论】:

        【解决方案4】:

        为了说明两个返回函数的promise之间的区别:

        const fs = require('fs')
        const util = require('util')
        
        const testFunc1 = async () => {
          fs.writeFileSync('text.txt', 'hello world')
          console.log('file write done with writeFileSync')
        }
        
        const writeFilePromisified = util.promisify(fs.writeFile)
        
        const testFunc2 = async () => {
          await writeFilePromisified('text.txt', 'hello world')
          console.log('file write done with promisified writeFile')
        }
        
        console.log('start test1')
        testFunc1().then(() => {
          console.log('promise 1 is fullfiled')
        })
        console.log('start test2')
        testFunc2().then(() => {
          console.log('promise 2 is fullfiled')
        })
        console.log('stop')
        

        输出将是:

        start test1
        file write done with writeFileSync
        start test2
        stop
        promise 1 is fullfiled
        file write done with promisified writeFile
        promise 2 is fullfiled
        

        所以就像 estus 所说的 testFunc1 阻止了主线程的执行。 testFunc2 不阻塞。

        【讨论】:

          【解决方案5】:

          fs.readFile 采用回调函数,这意味着它不会阻止脚本的执行。 fs.readFileSync 但是 接受回调,这意味着脚本的执行将暂停,直到进程完成。 使用 promisfy 是解决此问题的一种方法,对于小文件它不会产生影响,但对于大文件,您可能希望将 fs.readFileSync 转换为 Promise,这样您就不会阻止执行。 希望对您有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-09-16
            • 2019-04-29
            • 1970-01-01
            • 2020-10-31
            • 2018-10-17
            • 2019-12-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多