[英]Why would you ever call .call() on Observable functions?
我是Angular的相对初学者,我正在努力了解我从ng-bootstrap项目中读取的一些资源。 源代码可以在这里找到 。
我对ngOnInit中的代码感到非常困惑:
ngOnInit(): void {
const inputValues$ = _do.call(this._valueChanges, value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
});
const results$ = letProto.call(inputValues$, this.ngbTypeahead);
const processedResults$ = _do.call(results$, () => {
if (!this.editable) {
this._onChange(undefined);
}
});
const userInput$ = switchMap.call(this._resubscribeTypeahead, () => processedResults$);
this._subscription = this._subscribeToUserInput(userInput$);
}
在这些Observable函数上调用.call(...)
什么意义? 试图达到什么样的行为? 这是正常模式吗?
在我的Angular教育中,我已经做了大量关于Observables的阅读/观看(无双关语),但是我从未遇到过这样的事情。 任何解释将不胜感激
我个人的看法是,他们在RxJS 5.5之前的版本中使用了它,引入了可操作的运算符。 Angular内部使用相同的样式。 例如: https : //github.com/angular/angular/blob/master/packages/router/src/router_preloader.ts#L91 。
原因是默认情况下,他们必须使用rxjs/add/operators/XXX
修补Observable类。 这样做的缺点是某些第三方库正在修改全局对象,该对象可能会意外导致应用程序其他地方出现问题。 参见https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md#why
您可以在文件开头看到他们分别导入每个运算符https://github.com/ng-bootstrap/ng-bootstrap/blob/master/src/typeahead/typeahead.ts#L22-L25 。
因此,通过使用.call()
他们可以使用任何运算符,并且仍然避免修补Observable
类。
要了解它,首先您可以看一下预定义的JavaScript函数方法“ call”:
var person = {
firstName:"John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var myObject = {
firstName:"Mary",
lastName: "Doe",
}
person.fullName.call(myObject); // Will return "Mary Doe"
调用“ call”的原因是在对象“ person”中调用一个函数并将上下文传递给它“ myObject”。
类似地,此之所以称为“通话”的原因如下:
const inputValues$ = _do.call(this._valueChanges, value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
});
在提供上下文“ this._valueChanges”的同时,还提供了基于该上下文被调用的函数,即第二个参数,即匿名函数
value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
}
在您使用的示例中:
this._valueChanges是可观察到的输入事件
_do.call用于在事件输入发生时产生一些副作用,然后它返回源Observable的镜像Observable(事件Observable)
更新示例代码: https : //plnkr.co/edit/dJNRNI?p =preview
关于do
调用:
您可以像这样在Observable上调用它:
const source = Rx.Observable.of(1,2,3,4,5);
const example = source
.do(val => console.log(`BEFORE MAP: ${val}`))
.map(val => val + 10)
.do(val => console.log(`AFTER MAP: ${val}`));
const subscribe = example.subscribe(val => console.log(val));
在这种情况下,您不必将第一个参数作为上下文“可观察”传递。
但是,当像您所说的那样从自己的位置调用它时,您需要将第一个参数作为要调用的“可观察”传递。 那是不同的。
正如@Fan Cheung所提到的,如果您不想在自己的地方调用它,则可以执行以下操作:
const inputValues$=this._valueChanges.do(value=>{
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
})
我想
const inputValues$ = _do.call(this._valueChanges, value => {
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
});
相当于
const inputValues$=this._valueChanges.do(value=>{
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
})
在我看来,使用可观察对象并不是通常的模式(我认为这是相同的模式,但是写法不同)。 代码中的_do()用作独立函数,以回调作为参数,并且需要绑定到源Observable的范围
https://github.com/ReactiveX/rxjs/blob/master/src/operator/do.ts
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.