【问题标题】:How to write response to stream without waiting end of the fetch?如何在不等待提取结束的情况下将响应写入流?
【发布时间】:2020-11-01 11:16:36
【问题描述】:

我需要获取一个音频文件并写入一个目录。我担心我必须等待提取结束才能下载所有文件,然后写入/保存到文件。是否可以获取音频文件并同时写入文件。我只是认为它可能像“管道”。从服务中获取块,不要等待获取过程结束,只需将刚刚下载的块写入文件。那可能吗?如果有,可以举个例子吗?

这是我的代码:


const fetchAndWriteFiles = async (url, path) => {
  const res = await fetch(url)

  const fileStream = fs.createWriteStream(path)
  await new Promise((resolve, reject) => {
    res.body.pipe(fileStream)
    res.body.on('error', err => {
      reject(err)
    })
    fileStream.on('finish', function () {
      resolve()
    })
  })
}

【问题讨论】:

    标签: javascript node.js stream fetch node-fetch


    【解决方案1】:

    await fetch() 不会下载整个文件(如果文件很大)。它读取文件的第一个块(在我在调试器中查看的示例中,第一个块的长度为 16384 字节),从中提取标头,然后将第一个块的其余部分留在等待读出的流中.

    在您执行.pipe() 并清空现有流后,将读取文件的后续部分。文件的其余部分将以块的形式读取并以块的形式写入磁盘。要对此进行测试,您必须使用一个足够大的文件,以便读取/写入它需要多个块。

    事实上,当我在下载更大的响应时检测事物时,我看到在 await fetch() 完成之后发生了多次读取和写入。

    因此,您的代码似乎已经在做您似乎感兴趣的事情。如果您正在下载的页面很小(适合一个缓冲区),您将看不到多次读取/写入,因为整个响应可以一次读取,但对于较大的响应,它肯定会分块进行。块的大小还可能取决于数据从源到达的速度。

    【讨论】:

    • 非常感谢您的回答。如果你在我看到你回答之前问我,我会说那些代码(在我的问题中)正在等待下载所有文件,因为在 fetch 前面有一个等待。但是,正如你所说,它不会等待。这对我来说有点复杂,因为我一直在等待 await 将停止该过程直到获取结束。但无论如何,再次感谢你:) 我认为我需要阅读一些文章才能更好地理解..
    猜你喜欢
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多