3

假设我们有一个触发 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()或者整个方法可能是完全错误的。

很感谢任何形式的帮助。

4

2 回答 2

2

如果您阅读 的文档onErrorResumeNext

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

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

所以简而言之,你不想onErrorResumeNext在这里。

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

subject
    .concatMap(obs => obs.catch(Rx.Observable.of('error')))
    .subscribe(...)
于 2016-09-22T14:03:51.557 回答
0

observables 中的错误的想法与常规函数中的相同。这意味着如果您在常规函数中抛出错误 - 函数将不会返回任何内容。observables 也是如此 - 如果 observable 发出一个错误,这意味着流已完成并且没有更多值出现。所以是的,这从根本上是错误的。

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

希望有帮助。

于 2016-09-22T13:01:11.067 回答