为什么 RxJS subscribe 允许省略箭头函数和以下方法参数?

2024-03-21

最近需要使用RxJS。我尝试设计一个错误处理流程,但我发现了一些奇怪的语法传递方法参数:

.subscribe(
    x => {
    },
    console.warn // <- Why does this compile, and warn 'is not 7' in debug console?
);

最小复制链接:

https://stackblitz.com/edit/rxjs-6-5-error-handle-no-arrow-issue https://stackblitz.com/edit/rxjs-6-5-error-handle-no-arrow-issue

重现步骤:

  1. 使用 RxJS 6.5
  2. 创建一个返回 observable 的函数
  3. 订阅可观察的
  4. 将参数传递给订阅
  5. 只需使用,console.warn, 不喜欢,error => { console.warn(error); }

如果没有箭头函数,它仍然会将错误传递给console.warn。为什么?

Code:

import { throwError, concat, of } from "rxjs";
import { map } from "rxjs/operators";

const result = concat(of(7), of(8));

getData(result).subscribe(
  x => {
    console.log("typeof(x)", typeof(x));
    if (typeof(x) === 'string') {
      console.log("x  Error", x);
      return;
    }
    console.log("no error", x);
  },
  console.warn // <- Why does this compile, and warn 'is not 7' in debug console?
);

// pretend service method
function getData(result) {
  return result.pipe(
    map(data => {
      if (data !== 7) {
        throw "is not 7";
      }
      return data;
    })
  );
}

我尝试用谷歌搜索一些关键字,js,rxjs,角度,省略箭头函数,参数丢失,...但我无法找到这里使用的技术。

谁能提供解释此机制的链接?

以下两个问题相关但不解释行为,只是说“等效”:

The line

地图(this.extractTreeData)

相当于

地图(树=> this.extractTreeData(树))

如何将额外参数传递给 RxJS 映射运算符 https://stackoverflow.com/questions/53500562/how-to-pass-extra-parameters-to-rxjs-map-operator

为什么链式 Map 运算符中缺少参数 https://stackoverflow.com/questions/50648218/why-is-argument-missing-in-chained-map-operator


首先你需要了解你实际传递给的是什么.subscribe功能。本质上它接受三个可选参数next, error and complete。其中每个都是当源可观察对象发出相应通知时要执行的回调。

因此,当您使用箭头函数时,您可以定义一个就地回调函数。

sourceObservable.subscribe({
  next: (value) => { },
  error: (error) => { },
  complete: () => { }
});

相反,您可以单独定义函数并将其用作回调。

onNext(value) {
}

onError(error) {
}

onComplete() {
}

sourceObservable.subscribe({
  next: this.onNext,
  error: this.onError,
  complete: this.onComplete
});

现在这就是你所看到的。但是您传递的不是用户定义的函数,而是内置函数console.warn()功能。反过来,通知中的值将作为参数传递给回调函数。所以你的错误的价值is not 7作为参数发送给console.warn()然后它会完成它的工作(即打印到控制台)。

然而有一个问题。如果您想使用任何类成员变量this回调中的关键字,它会抛出一个错误,指出该变量未定义。那是因为this指回调中函数的范围,而不是类。克服这个问题的一种方法是使用箭头函数(我们已经看到了)。或者使用bind() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind函数绑定的含义this类的关键字。

sourceObservable.subscribe({
  next: this.onNext.bind(this),
  error: this.onError.bind(this),
  complete: this.onComplete.bind(this)
});

因此,如果您只想拥有错误回调,您可以明确声明它并忽略其他回调。

sourceObservable.subscribe({ error: console.warn });

现在关于你的问题“为什么函数调用中没有括号”, 讨论了here https://stackoverflow.com/a/15886327/6513921 and here https://stackoverflow.com/a/19732998/6513921。参数需要对函数的引用,函数名称表示它们的引用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 RxJS subscribe 允许省略箭头函数和以下方法参数? 的相关文章

随机推荐