如何将节点可读流转换为RX observable

时间:2017-01-08 20:27:31

标签: javascript node.js rxjs rxjs5

如果我有一个Node js流,例如来自process.stdinfs.createReadStream之类的东西,我如何使用RxJs5将其转换为RxJs Observable流?

我发现RxJs-Node有一个fromReadableStream方法,但看起来好像近一年没有更新。

5 个答案:

答案 0 :(得分:12)

对于任何寻找此项目的人,请遵循Mark的建议I adapted rx-node fromStream implementation for rxjs5

import { Observable } from 'rxjs';

// Adapted from https://github.com/Reactive-Extensions/rx-node/blob/87589c07be626c32c842bdafa782fca5924e749c/index.js#L52
export default function fromStream(stream, finishEventName = 'end', dataEventName = 'data') {
  stream.pause();

  return new Observable((observer) => {
    function dataHandler(data) {
      observer.next(data);
    }

    function errorHandler(err) {
      observer.error(err);
    }

    function endHandler() {
      observer.complete();
    }

    stream.addListener(dataEventName, dataHandler);
    stream.addListener('error', errorHandler);
    stream.addListener(finishEventName, endHandler);

    stream.resume();

    return () => {
      stream.removeListener(dataEventName, dataHandler);
      stream.removeListener('error', errorHandler);
      stream.removeListener(finishEventName, endHandler);
    };
  }).share();
}

请注意,它本质上打破了流的所有背压功能。可观察的是推动技术。所有输入块将被读取并尽快推送给观察者。根据您的情况,它可能不是最佳解决方案。

答案 1 :(得分:2)

以下内容适用于v4和v5(免责声明未经测试):

return {
 FindUserDetail: function(userid) {
   return $http.get(`${GENERAL_CONFIG.ServiceWebApiUrl}/GetUserDetailById?UserId=${userid}`);
 }
};

答案 2 :(得分:2)

上述答案将有效,但不支持背压。如果您尝试使用 createReadStream 读取大文件,它们将读取内存中的整个内容。

这是我的背压支持实现: rxjs-stream

答案 3 :(得分:1)

RxJs-Node实现基于RxJs4,但可以移植到RxJs5而不需要太多工作https://github.com/Reactive-Extensions/rx-node/blob/87589c07be626c32c842bdafa782fca5924e749c/index.js#L52

答案 4 :(得分:0)

由于 Node v11.14.0 流支持 for await https://nodejs.org/api/stream.html#stream_readable_symbol_asynciterator

这意味着您可以将 stream 传递给 from() 运算符。

在后台 rxjs(v7.x.x) 将调用 fromAsyncIterable() 将返回 Observable