在subscriber.error 语句之后没有触发subscriber.next

分享于2022年07月17日 angular javascript observable rxjs 问答
【问题标题】:在subscriber.error 语句之后没有触发subscriber.next()(subscriber.next() is not firing after subscriber.error statement)
【发布时间】:2022-06-22 18:00:17
【问题描述】:

根据输入数据,我想确定它是否是有效数据,并将 observable 发送到结束。

我已尝试创建一个可观察且顺序的 subscribe.next() 工作正常,但出现任何错误,然后没有任何语句正常工作。

const observable = new Observable((subscriber) => {
  subscriber.next(1);
  subscriber.next(2);
  subscriber.error('failed this after second');
  subscriber.next(3);
  subscriber.next(4);
  subscriber.complete();
});

observable.subscribe({
  next(x) {
    console.log('got value ' + x);
  },
  error(err) {
    console.error('something wrong occurred: ' + err);
  },
  complete() {
    console.log('done');
  },
});

当前输出:

  • 得到值 1
  • 得到值 2
  • 发生错误:第二次后失败

预期输出

  • 得到值 1
  • 得到值 2
  • 发生错误:第二次后失败
  • 得到值 3
  • 得到值 4
  • 完成

这是 stackblitz 链接 https://stackblitz.com/edit/zlksm5?devtoolsheight=50&file=index.ts


【解决方案1】:

The Observable Contract

OnError:

  • 表示 Observable 已 终止 并出现指定的错误条件,并且它将 不再发射任何项目

强调我的。

如果你想要在完成后继续运行的东西,你不需要 observable。

寻求解决方案

只需将您的错误作为值发出即可。你可以(例如)将你的发射封装在 RxJS Notification 对象中,这样你就可以 materialize dematerialize observables 并保持一个一致的发射 API。

例如:

const observable = new Observable(subscriber => {
  subscriber.next({ kind: "N", value: 1 });
  subscriber.next({ kind: "N", value: 2 });
  subscriber.next({ kind: "E", error: new Error("failed this after second") });
  subscriber.next({ kind: "N", value: 3 });
  subscriber.next({ kind: "N", value: 4 });
  subscriber.next({ kind: "C" });
  subscriber.complete();
});

/**** Alternative written more succinctly ****/

const observable = of(
  { kind: "N", value: 1 },
  { kind: "N", value: 2 },
  { kind: "E", error: new Error("failed this after second") },
  { kind: "N", value: 3 },
  { kind: "N", value: 4 },
  { kind: "C" }
);

observable.subscribe((notification) => {
  switch (notification.kind) {
    case "N":
      console.log("got value ", notification.value);
      break;
    case "E":
      console.error("something wrong occurred: ", notification.error.message);
      break;
    case "C":
      console.log("done");
  }
});