繁体   English   中英

将 Node 流转换为 Rx.js Observables

[英]Converting Node streams into Rx.js Observables

我正在努力将 Node 流转换为 Rxjs Observables。

当我尝试 1 个 URL 时,流式传输本身效果很好。但是,当我尝试在一组 URL 上映射相同的函数时,我收到错误消息。

我正在使用 Rx.Node 将流转换为 Observable。

这就是我目前正在尝试的

// data_array is an array of 10 urls that I'm scraping data from. 
let parentStream = Rx.Observable.from(data_array);

parentStream.map(createStream).subscribe(x => console.log(x), (e)=> console.log('Error', e), console.log('Complete'));

function createStream(url){
  return RxNode.fromStream(x(url, '#centercol ul li', [{name: 'a', link: 'a@href'}]).write().pipe(JSONStream.parse('*')))
}

但这是输出X 10(data_array中的URL数)

RefCountObservable {
 source:
  ConnectableObservable {
   source: AnonymousObservable { source: undefined, __subscribe: [Function] },
 _connection: null,
 _source: AnonymousObservable { source: [Object], __subscribe: [Function: subscribe] },
 _subject:
  Subject {
    isDisposed: false,
    isStopped: false,
    observers: [],
    hasError: false } },
_count: 0,
_connectableSubscription: null }

我首先认为 flatMap 会起作用,因为它在一个 observable 中展平了 observable....但是当我尝试 flatMap 时,我得到了这个:

Complete
Error TypeError: unknown type returned

但是,如果我这样做:

这适用于 1 URL ,但我无法在一个流中捕获 data_array 中的所有 URL。

let stream = RxNode.fromStream(x(url, '#centercol ul li', [{name: 'a', link: 'a@href'}]).write().pipe(JSONStream.parse('*')))

stream.subscribe(x => console.log(x), (e)=> console.log('Error', e), console.log('Complete'))

我觉得我误解了一些东西,不仅因为它清除对多个 URL 不起作用,而且即使它在第二个示例中起作用......我在所有数据进入之前首先得到“完成”。

显然,我误解了一些东西。 任何帮助都会很棒。 谢谢。

*更新*

我尝试了不同的路径,它有效,但不使用节点流。 节点流将是理想的,所以仍然想让上面的例子工作。

我接下来使用的方法是在我的网页抓取功能周围包装一个 promise,即下面的抓取 这是有效的,但结果是十个巨大的数组,每个数组中包含来自每个 URL 的所有数据。 我真正想要的是一个对象流,我可以在数据对象通过时组成一系列转换。

这是不同的,但工作方法:

let parentStream = Rx.Observable.from(data_array);

parentStream.map(url => {
    return Rx.Observable.defer(() => {
        return scrape(url, '#centercol ul li', [{name: 'a', link: 'a@href'}]);
    })
})
    .concatAll()
    .subscribe(x => console.log(x), (e)=> console.log('Error', e), console.log('Complete'));

function scrape(url, selector, scope) {
    return new Promise(
        (resolve, reject) => x(
            url,
            selector,
            scope
        )((error, result) => error != null ? reject(error) : resolve(result))
    );
}

*解决方案*我想通了。 我附上了下面的解决方案:

我选择使用 Rx.Observable.fromEvent(),而不是使用 RxNode。

节点流会发出事件,无论是新数据、错误还是完成。

因此fromEvent静态运算符正在侦听 'data' 事件并为每个事件创建一个新的 Observable。

然后我合并所有这些,然后订阅。 这是代码:

let parentStream = Rx.Observable.from(data_array);
parentStream.map((url)=> { return createEventStream(url); } ).mergeAll().subscribe(x => console.log(x), (e)=> console.log('Error', e), console.log('Complete'));

function createEventStream(url){
  return Rx.Observable.fromEvent(x(url, '#centercol ul li', [{name: 'a', link: 'a@href'}]).write().pipe(JSONStream.parse('*')), 'data');
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM