簡體   English   中英

如何從內部有 Observable 訂閱的 function 返回值?

[英]How to return value from function which has Observable subscription inside?

我不知道如何從存在 Observable 的 function 返回的 Observable 中提取值。 我只需要從中返回一個值,沒有別的。

有效的當前版本

function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            console.log(data)
        }
    )
}
getValueFromObservable()

我需要這個工作,function 返回值,然后:

function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            return data
        }
    )
}
console.log(getValueFromObservable())

我在這里做錯了什么?

編輯:更新代碼以反映在 RXJS 的最新版本中對管道工作方式所做的更改。 所有運算符(以我的示例為例)現在都包含在 pipe() 運算符中。

我意識到這個問題是很久以前的事了,現在你肯定有一個合適的解決方案,但對於任何尋找這個問題的人,我建議用 Promise 來解決它以保持異步模式。

更詳細的版本是創建一個新的 Promise:

function getValueFromObservable() {
    return new Promise(resolve=>{
        this.store.pipe(
           take(1) //useful if you need the data once and don't want to manually cancel the subscription again
         )
         .subscribe(
            (data:any) => {
                console.log(data);
                resolve(data);
         })
    })
}

在接收端,您將“等待”承諾以如下方式解決:

getValueFromObservable()
   .then((data:any)=>{
   //... continue with anything depending on "data" after the Promise has resolved
})

更精簡的解決方案是使用 RxJS 的 .toPromise() 代替:

function getValueFromObservable() {
    return this.store.pipe(take(1))
       .toPromise()   
}

接收方當然和上面一樣。

這不是使用Observable完全正確的想法

在組件中,您必須聲明將持有對象的類成員(您將在組件中使用的東西)

export class MyComponent {
  name: string = "";
}

然后Service將返回一個Observable

getValueFromObservable():Observable<string> {
    return this.store.map(res => res.json());
}

Component應該准備好能夠從中檢索值:

OnInit(){
  this.yourServiceName.getValueFromObservable()
    .subscribe(res => this.name = res.name)
}

您必須將Observable的值分配給變量:

並且您的模板將消耗變量name

<div> {{ name }} </div>

另一種使用Observable是通過async管道http://briantroncone.com/?p=623

注意:如果這不是您要問的問題,請使用更多詳細信息更新您的問題

如果您想預訂閱將返回的同一個 Observable,只需使用

.do():

function getValueFromObservable() {
    return this.store.do(
        (data:any) => {
            console.log("Line 1: " +data);
        }
    );
}

getValueFromObservable().subscribe(
        (data:any) => {
            console.log("Line 2: " +data)
        }
    );

問題是數據是在 observable 中捕獲的,我可以通過控制台記錄它。 我想通過調用它所在的函數來返回該值和 console.log 或來自不同文件的任何內容。

看起來您正在 observable 中尋找“當前值”getter,當它發射時和發射后。

SubjectObservable沒有這樣的東西。 當一個值被發出時,它被傳遞給它的訂閱者並且Observable用它完成。

您可以使用BehaviorSubject來存儲最后發出的值並立即將其發送給新訂閱者。

它還有一個getValue()方法來獲取當前值;

進一步閱讀:

RxJS 行為主題

如何獲取 RxJS Subject 或 Observable 的當前值?

可以從任何位置檢索可觀察值。 源序列首先被推送到一個能夠在別處發射的特殊觀察者 這是通過 Reactive Extensions (RxJS) 中的Subject 類實現的。

var subject = new Rx.AsyncSubject();  // store-last-value method

將值存儲到觀察者上

subject.next(value); // store value
subject.complete(); // publish only when sequence is completed

要從其他地方檢索值,請像這樣訂閱觀察者:

subject.subscribe({
  next: (response) => {
      //do stuff. The property name "response" references the value
  }
});

Subjects 既是 Observables 又是 Observers。 對於其他使用場景,還有其他主題類型,例如 BehaviourSubject 和 ReplaySubject。

不要忘記導入 RxJS。

var Rx = require('rxjs');

雖然以前的答案可能以某種方式起作用,但我認為如果您想繼續使用 observable,使用 BehaviorSubject 是正確的方法。

示例:

    this.store.subscribe(
        (data:any) => {
            myService.myBehaviorSubject.next(data)
        }
    )

在服務中:

let myBehaviorSubject = new BehaviorSubjet(value);

在 component.ts 中:

this.myService.myBehaviorSubject.subscribe(data => this.myData = data)

我希望這會有所幫助!

例如,這是我的 html 模板:

<select class="custom-select d-block w-100" id="genre" name="genre"
                  [(ngModel)]="film.genre"
                  #genreInput="ngModel"
                  required>
            <option value="">Choose...</option>
            <option *ngFor="let genre of genres;" [value]="genre.value">{{genre.name}}</option>
          </select>

這是與我的組件中的模板綁定的字段:

  // Genres of films like action or drama that will populate dropdown list.
  genres: Genre[];

我從服務器動態獲取電影類型。 為了與服務器通信,我創建了FilmService

這是與服務器通信的方法:

 fetchGenres(): Observable<Genre[]> {
    return this.client.get(WebUtils.RESOURCE_HOST_API + 'film' + '/genre') as Observable<Genre[]>;
  }

為什么這個方法返回Observable<Genre[]>而不是類似於Genre[]東西?

JavaScript 是async ,它不會等待一個方法在一個昂貴的過程之后返回值。 昂貴的意思是一個需要時間來返回值的過程。 就像從服務器獲取數據一樣。 所以你必須返回 Observable 的引用並訂閱它。

例如在我的組件中:

ngOnInit() {
    this.filmService.fetchGenres().subscribe(
      val => this.genres = val
    );
  }

在單線程、異步、面向承諾、響應式趨勢的 javascript async/await世界中, async/await是命令式程序員最好的朋友:

(async()=>{

    const store = of("someValue");
    function getValueFromObservable () {
        return store.toPromise();
    }
    console.log(await getValueFromObservable())

})();

如果store是多個值的序列:

  const aiFrom = require('ix/asynciterable').from;
  (async function() {

     const store = from(["someValue","someOtherValue"]);
     function getValuesFromObservable () {
        return aiFrom(store);
     }
     for await (let num of getValuesFromObservable()) {
       console.log(num);
     }
  })();
function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            return data
        }
    )
}
console.log(getValueFromObservable())

在上面的例子中,console.log 在 promise 被解決之前運行,所以沒有顯示任何值,將其更改為以下

function getValueFromObservable() {
    return this.store
}

getValueFromObservable()
 .subscribe((data: any) => {
    // do something here with data
    console.log(data);
});

其他解決方案是當您需要 getValueFromObservable 中的數據以使用運算符返回可觀察對象並訂閱該函數時。

 function getValueFromObservable() {
        return this.store.subscribe((data: any) => {
            // do something with data here
            console.log(data);
            //return again observable.
            return of(data);
       })
    }

    getValueFromObservable()
     .subscribe((data: any) => {
        // do something here with data
        console.log(data);
    });

體面的方法是從函數返回 observable 並在任何需要的地方訂閱它,因為 observables 是惰性的,它們只有在訂閱時才會開始發出值。

在這里,我有一個更有趣的事件驅動解決方案,我最初使用它。 以下示例通過使用 nodejs 的“ events ”模塊來完成此操作。 您可以將它與存在類似模塊的其他框架一起使用注意:語法和樣式可能會根據所使用的模塊而變化)。

var from =require("rxjs").from;
var map = require("rxjs/operators").map;
var EventEmitter = require("events");

function process(event) {
    from([1,2,3]).pipe(
        map(val => `The number is:: ${val}`)
    ).subscribe((data) => {
       event.emit("Event1", data); //emit value received in subscribe to the "Event1" listener
    });
}

function main() {
   class Emitter extends EventEmitter{};
    var event = new Emitter(); //creating an event
    event.on("Event1", (data)=>{ //listening to the event of name "Event1" and callback to log returned result
        console.log(data); //here log, print, play with the data you receive
    });
    process(event); //pass the event to the function which returns observable.
}

main(); //invoke main function

這只是一個例子,展示了我們可以通過發送和監聽的方法從不同地方傳遞數據的想法。 這也稱為事件驅動代碼。

從 function 返回一個 observable。

rxjs函數.ts

import { Observable } from 'rxjs'

export function getValueFromObservable() {

    return new Observable( (obs) => {
        obs.next(5);
    })
}

主.ts

import { getValueFromObservable } from "./rxjsFunction";

getValueFromObservable().subscribe((value) => {
    next: console.log(value);
});

我想檢查數據是否存儲在客戶端上,或者我是否必須通過 API 調用從服務器獲取數據。 然后返回一個新的觀察者並訂閱它就可以了。 第一次從服務器獲取數據,之后返回 this.allUsers,因為我在調用 API 並返回數據后設置了此數據。

    private _allUsers: EnconUser[] = undefined;
    get allUsers(): EnconUser[]
    {
      return this._allUsers;
    }
    set allUsers(value: EnconUser[])
    {
      this.storage.store('allUsers', value);
      this._allUsers = value;
    }

    public getAllUsers() : Observable<EnconUser[]>
    {
      if (this.allUsers == undefined)
      {
        return new Observable((obs) => {this.httpClient.get<EnconUser[]>(`http://api/getallusers`).subscribe(data=>{this.allUsers=data; obs.next(data); })});
      }
      else
      {
       return new Observable((obs) => {
        obs.next(this.allUsers);
        });
      }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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