为什么你会在 Observable 函数上调用 .call() ?
Why would you ever call .call() on Observable functions?
我是 Angular 的相对初学者,我正在努力理解我从 ng-bootstrap 项目中阅读的一些资料。 The source code can be found here。
我对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 教育的一部分,我已经 reading/watching 做了很多关于 Observables 的事情(没有双关语意),但我从来没有遇到过这样的事情。任何解释将不胜感激
我想
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);
}
})
在我看来,这不是使用 observable 的常用模式(我认为它是相同的模式,但以不同的方式编写)。代码中的 _do() 被用作独立函数,将回调作为参数并需要绑定到源 Observable
的范围
https://github.com/ReactiveX/rxjs/blob/master/src/operator/do.ts
我个人的看法是,他们在 5.5 之前的 RxJS 中使用了它,它引入了可出租运算符。 Angular 在内部使用相同的样式。例如:https://github.com/angular/angular/blob/master/packages/router/src/router_preloader.ts#L91.
这样做的原因是默认情况下他们必须用 rxjs/add/operators/XXX
修补 Observable class。这样做的缺点是某些第 3 方库正在修改全局对象,这可能会意外地导致您应用程序中其他地方出现问题。参见 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
class。
要理解它,首先你可以看一下预定义的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"。
同样,下面调用"call"的原因:
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 是为了在事件输入发生时做一些副作用,然后它 returns 源 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));
在这种情况下,您不必将第一个参数作为上下文传递 "Observable"。
但是当你像你说的那样从它自己的地方调用它时,你需要将第一个参数作为你想要调用的 "Observable" 传递。就是不一样。
正如@Fan Cheung 提到的,如果你不想从它自己的地方调用它,你可以这样做:
const inputValues$=this._valueChanges.do(value=>{
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
})
我是 Angular 的相对初学者,我正在努力理解我从 ng-bootstrap 项目中阅读的一些资料。 The source code can be found here。
我对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 教育的一部分,我已经 reading/watching 做了很多关于 Observables 的事情(没有双关语意),但我从来没有遇到过这样的事情。任何解释将不胜感激
我想
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);
}
})
在我看来,这不是使用 observable 的常用模式(我认为它是相同的模式,但以不同的方式编写)。代码中的 _do() 被用作独立函数,将回调作为参数并需要绑定到源 Observable
的范围https://github.com/ReactiveX/rxjs/blob/master/src/operator/do.ts
我个人的看法是,他们在 5.5 之前的 RxJS 中使用了它,它引入了可出租运算符。 Angular 在内部使用相同的样式。例如:https://github.com/angular/angular/blob/master/packages/router/src/router_preloader.ts#L91.
这样做的原因是默认情况下他们必须用 rxjs/add/operators/XXX
修补 Observable class。这样做的缺点是某些第 3 方库正在修改全局对象,这可能会意外地导致您应用程序中其他地方出现问题。参见 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
class。
要理解它,首先你可以看一下预定义的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"。
同样,下面调用"call"的原因:
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 是为了在事件输入发生时做一些副作用,然后它 returns 源 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));
在这种情况下,您不必将第一个参数作为上下文传递 "Observable"。
但是当你像你说的那样从它自己的地方调用它时,你需要将第一个参数作为你想要调用的 "Observable" 传递。就是不一样。
正如@Fan Cheung 提到的,如果你不想从它自己的地方调用它,你可以这样做:
const inputValues$=this._valueChanges.do(value=>{
this._userInput = value;
if (this.editable) {
this._onChange(value);
}
})