【问题标题】:No data after piping response stream管道响应流后无数据
【发布时间】:2019-10-10 11:55:29
【问题描述】:

使用 Electron 的 net 模块,目的是获取资源,并在收到响应后将其通过管道传输到可写流,如下所示:

const stream = await fetchResource('someUrl');
stream.pipe(fs.createWriteStream('./someFilepath'));

fetchResource的简化实现如下:

import { net } from 'electron';

async function fetchResource(url) {
  return new Promise((resolve, reject) => {
    const data = [];

    const request = net.request(url);
    request.on('response', response => {
      response.on('data', chunk => {
        data.push(chunk);
      });
      response.on('end', () => {
        // Maybe do some other stuff with data...
      });
      // Return the response to then pipe...
      resolve(response);
    });
    request.end();
  });
}

响应最终是 IncomingMessage 的一个实例,它根据节点 docs 实现了一个 Readable Stream 接口,因此它应该能够通过管道传输到一个写入流。

主要问题是最终在流中没有数据通过管道传输????

【问题讨论】:

    标签: node.js electron


    【解决方案1】:

    回答我自己的问题,但问题来自多个来源:已解决的承诺和 'data' 事件。事件侦听器源在已解决的 Promise 到达之前刷新了所有数据。

    一种解决方案是将流分叉到一个新的流中,如果不止一次源尝试从它进行管道传输,则该流不会与原始流竞争。

    import stream from 'stream';
    
    // ...make a request and get a response stream, then fork the stream...
    const streamToResolve = response.pipe(new stream.PassThrough());
    
    // Listen to events on response and pipe from it
    // ...
    
    // Resolve streamToResolve and separately pipe from it
    // ...
    

    【讨论】:

    • 与 js 代码相比,PassThrough 另一个 qa 提到的竞争条件似乎是文件写入的概率。如果你愿意,你可以修改你的原始函数来处理 Promise 中的管道/写入和数据处理。
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    相关资源
    最近更新 更多