RxJS 5任务队列,如果任务失败则继续

时间:2016-09-22 09:55:16

标签: javascript ajax rxjs rxjs5 reactive-extensions-js

想象一下,我们有一个激活AJAX请求的HTML页面。我们希望确保按顺序执行AJAX请求。下一个AJAX请求不会被触发,直到前一个请求完成或错误。

我尝试使用RxJS concatMap通过任务队列对此进行建模。每个AJAX请求都建模为Observable。如果AJAX请求成功完成,一切都运行良好,但如果错误,则不执行队列中的下一个任务。

以下示例使用setTimeout()来模拟长时间运行的异步任务:

  function identity(observable) {
    return observable;
  }

  function createTaskQueue() {
    var subject= new Rx.Subject();

    subject
    .concatMap(identity)
    .onErrorResumeNext(Rx.Observable.of('error'))
    .subscribe(function(data) {
      console.log('onNext', data);
    }, 
    function(error) {
      console.log('onError', error);
    });

    return {
      addTask: function(task) {
        subject.next(task);
      }
    }
  }

  function createTask(data, delay) {
    return Rx.Observable.create(function(obs) {
      setTimeout(function() {
        obs.next(data);
        obs.complete();
      }, delay);
    });
  }

  function createErrorTask(data, delay) {
    return Rx.Observable.create(function(obs) {
      setTimeout(function() {
        obs.error('Error: ' + data);
        obs.complete();
      }, delay);
    });
  }

  var taskQueue = createTaskQueue();

  taskQueue.addTask(createTask(11, 500))
  taskQueue.addTask(createTask(22, 200));
  taskQueue.addTask(createErrorTask(33, 1000));
  taskQueue.addTask(createTask(44, 300));
  taskQueue.addTask(createErrorTask(55, 300));
  taskQueue.addTask(createTask(66, 300));

以下是一个可执行示例:https://jsfiddle.net/artur_ciocanu/s6ftxwnf/

当我运行此代码时,以下内容将打印到控制台: onNext 11 onNext 22 onNext error

这是预料之中的,但我想知道为什么44,55等其他任务没有被执行。

我很确定我在使用onErrorResumeNext()做一些愚蠢的事情,或者整个方法可能完全错误。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

如果您阅读了onErrorResumeNext的文档,

  

继续正常终止或由a终止的可观察序列   下一个可观察序列或Promise的异常。

这意味着当您的source observable遇到错误时,它会切换到您传递给onErrorResumeNext的任何内容。这里发生的是Rx.of(...)在发出其值后立即终止。因此,你观察到的行为。

简而言之,您不希望onErrorResumeNext在这里。

您可以改为.catch(...)可能发出错误的流。所以,像:

subject
    .concatMap(obs => obs.catch(Rx.Observable.of('error')))
    .subscribe(...)

答案 1 :(得分:0)

可观察量中的错误的想法与常规函数中的相同。这意味着如果在常规函数中抛出错误 - 函数将不返回任何内容。与observables相同 - 如果observable发出错误,表示流已完成且不再有值。所以是的,这根本就是错误的。

更好(正确)的方法是拥有一个响应流,其中下一个值可以是成功响应或错误响应。如果您需要将它们分开,您可以稍后将响应流分成两个成功/错误响应。

希望有所帮助。