RxJS:随时间动态组合多个可观察对象

时间:2017-08-27 13:18:24

标签: node.js asynchronous recursion rxjs

我的问题是递归的,我不知道我的Observable complete()何时处于递归函数中。

基本上,我的功能是删除一个具有分页功能的网站,并且它返回一个Observable,它会推送"解析"使用.next(data)方法在每个页面上找到的项目,并递归执行,直到我们发现自己在最后一页,然后我们触发主题的.complete()方法。

我使用concat(Observable)方法以递归的方式将新的Observable与当前的Observable连接起来,但它似乎不起作用,当我订阅我的observable时我只得到了它的项目第一页,这让我猜测concat()方法对我的情况不起作用。

以下是我的功能代码的简化版本。

```

crawlList(url) {
    let obsSubject = new Subject();
    request(url, function (err, response, body) {
        //check if everything is alright...
        //parsing data...
        obsSubject.next(parsedData);
        //now we check if we can still paginate (we are not in the last page)
        //if so, we concat our observable with the new observable recursivly
        obsSubject.concat(crawList(url))
        //else ,(we are in the last page
        obsSubject.complete();
    });
    return obsSubject;
}

```

1 个答案:

答案 0 :(得分:2)

一般情况下,请避免使用Subject,除非您某些,否则您无法使用运营商。

在这种情况下,我希望expand可以在这里工作。将前一个流的结果反馈给运算符,以便可以递归执行。

类似的东西:

// Convert the callback into an Observable
const rxRequest = Rx.Observable.bindNodeCallback(
  request,
  (response, body) => ({response, body})
);    

// Feed the initial data set, by default we should continue
Observable.of({url: baseUrl, shouldContinue: true})
  .expand(({url, shouldContinue}) => {
    // Return an empty stream to cancel the Observable
    // note this is from the *previous* iteration
    if (!shouldContinue)
      return Rx.Observable.empty();

    // This is how we call the newly created method
    return rxRequest(url)
      .map(({response, body}) => 
        // Parse data
        // Check if you should continue or not
        // We still need to emit this data so we can't cancel until the next
        // go-around
        ({url: newUrl, data: parsedData, shouldContinue})
      );
  })
  // Downstream only cares about the data part
  .pluck('data')