簡體   English   中英

為什么要在Observable函數上調用.call()?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM