Saya tidak tahu cara mengekstrak nilai dari Observable untuk dikembalikan oleh fungsi di mana Observable ada. Saya hanya perlu nilai darinya untuk dikembalikan, tidak ada yang lain.
Versi saat ini yang berfungsi
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
console.log(data)
}
)
}
getValueFromObservable()
Saya membutuhkan ini untuk bekerja, berfungsi untuk mengembalikan nilai, dan kemudian:
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
return data
}
)
}
console.log(getValueFromObservable())
Apa yang saya lakukan salah di sini?
typescript
angular
rxjs
rxjs5
Teddy
sumber
sumber
subscribe
Jawaban:
EDIT: kode yang diperbarui untuk mencerminkan perubahan yang dilakukan pada cara kerja pipa di versi RXJS yang lebih baru. Semua operator (ambil contoh saya) sekarang dibungkus ke dalam operator pipe ().
Saya menyadari bahwa Pertanyaan ini sudah cukup lama dan Anda pasti memiliki solusi yang tepat sekarang, tetapi bagi siapa pun yang mencari ini, saya sarankan untuk menyelesaikannya dengan Janji untuk mempertahankan pola asinkron.
Versi yang lebih panjang akan membuat Janji baru:
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); }) }) }
Di pihak penerima, Anda kemudian harus "menunggu" janji diselesaikan dengan sesuatu seperti ini:
getValueFromObservable() .then((data:any)=>{ //... continue with anything depending on "data" after the Promise has resolved })
Solusi yang lebih ramping akan menggunakan RxJS '.toPromise () sebagai gantinya:
function getValueFromObservable() { return this.store.pipe(take(1)) .toPromise() }
Sisi penerima tetap sama seperti di atas tentunya.
sumber
getValueFromObservable
fungsi Anda ?Ini bukanlah ide penggunaan yang benar
Observable
Di dalam komponen Anda harus mendeklarasikan anggota kelas yang akan menampung sebuah objek (sesuatu yang akan Anda gunakan dalam komponen Anda)
export class MyComponent { name: string = ""; }
Kemudian a
Service
akan mengembalikan Anda sebuahObservable
:getValueFromObservable():Observable<string> { return this.store.map(res => res.json()); }
Component
harus mempersiapkan diri untuk dapat mengambil nilai darinya:OnInit(){ this.yourServiceName.getValueFromObservable() .subscribe(res => this.name = res.name) }
Anda harus menetapkan nilai dari sebuah
Observable
ke variabel:Dan template Anda akan menggunakan variabel
name
:Cara lain untuk menggunakan
Observable
adalah melaluiasync
pipa http://briantroncone.com/?p=623Catatan : Jika bukan itu yang Anda tanyakan, harap perbarui pertanyaan Anda dengan lebih detail
sumber
name
tersedia di luar callback dengan menugaskannya kename
variabel komponen . Tidak mungkin untuk kembali secaraname
sinkron dalam kasus Anda.Oninit
seperti itu, Bagaimana jika saya perlu mengembalikan secara eksplisit, kode panggilan saya terlihat seperti inithis.actions$.ofType(SearchActions.SEARCH_MULTIPLE_NEW_QUERY).map(toPayload).fnWithMultipleAsyncReturns()
Jika Anda ingin berlangganan Observable yang sama yang akan dikembalikan, gunakan saja
function getValueFromObservable() { return this.store.do( (data:any) => { console.log("Line 1: " +data); } ); } getValueFromObservable().subscribe( (data:any) => { console.log("Line 2: " +data) } );
sumber
.map(data => data)
yang melakukan hal yang sama dan kemudian berlangganan di mana pun Anda mengharapkan hasilnyado
sekarang dipanggiltap
dan Anda harus menggunakannya dalam pipa. Perhatikan juga bahwatap
mengambil beberapa parameter untuk penangan yang berbeda sepertinext
,complete
danerror
.Sepertinya Anda sedang mencari getter "nilai saat ini" di dalam sebuah observable, saat ia memancarkan dan setelah emisi.
Subject
danObservable
tidak memiliki hal seperti itu. Ketika sebuah nilai dipancarkan, itu diteruskan ke pelanggannya danObservable
selesai dengannya.Anda dapat menggunakan
BehaviorSubject
yang menyimpan nilai emisi terakhir dan segera memancarkannya ke pelanggan baru.Ia juga memiliki
getValue()
metode untuk mendapatkan nilai saat ini;Bacaan lebih lanjut:
RxJS BehaviorSubject
Bagaimana cara mendapatkan nilai RxJS Subject atau Observable?
sumber
Nilai yang dapat diamati dapat diambil dari lokasi manapun. Urutan sumber pertama - tama didorong ke pengamat khusus yang dapat memancarkan di tempat lain. Ini dicapai dengan kelas Subjek dari Ekstensi Reaktif (RxJS).
var subject = new Rx.AsyncSubject(); // store-last-value method
Simpan nilai ke pengamat .
subject.next(value); // store value subject.complete(); // publish only when sequence is completed
Untuk mengambil nilai dari tempat lain, berlangganan pengamat seperti ini:
subject.subscribe({ next: (response) => { //do stuff. The property name "response" references the value } });
Subjek adalah Observable dan Observers. Ada jenis Subjek lain seperti BehaviourSubject dan ReplaySubject untuk skenario penggunaan lainnya.
Jangan lupa untuk mengimpor RxJS.
var Rx = require('rxjs');
sumber
Meskipun jawaban sebelumnya mungkin berhasil, saya pikir menggunakan BehaviorSubject adalah cara yang benar jika Anda ingin terus menggunakan observable.
Contoh:
this.store.subscribe( (data:any) => { myService.myBehaviorSubject.next(data) } )
Dalam Layanan:
let myBehaviorSubject = new BehaviorSubjet(value);
Di component.ts:
this.myService.myBehaviorSubject.subscribe(data => this.myData = data)
Saya harap ini membantu!
sumber
Misalnya ini adalah template html saya:
<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>
Ini adalah bidang yang diikat dengan templat dari Komponen saya:
// Genres of films like action or drama that will populate dropdown list. genres: Genre[];
Saya mengambil genre film dari server secara dinamis. Untuk berkomunikasi dengan server yang telah saya buat
FilmService
Ini adalah metode yang mengkomunikasikan server:
fetchGenres(): Observable<Genre[]> { return this.client.get(WebUtils.RESOURCE_HOST_API + 'film' + '/genre') as Observable<Genre[]>; }
Mengapa metode ini mengembalikan
Observable<Genre[]>
bukan sesuatu sepertiGenre[]
?JavaScript adalah
async
dan tidak menunggu metode untuk mengembalikan nilai setelah proses yang mahal. Dengan mahal yang saya maksud adalah proses yang membutuhkan waktu untuk mengembalikan nilai. Seperti mengambil data dari server. Jadi, Anda harus mengembalikan referensi Observable dan berlangganan.Misalnya di Komponen saya:
ngOnInit() { this.filmService.fetchGenres().subscribe( val => this.genres = val ); }
sumber
function getValueFromObservable() { this.store.subscribe( (data:any) => { return data } ) } console.log(getValueFromObservable())
Dalam kasus di atas, console.log berjalan sebelum promise diselesaikan sehingga tidak ada nilai yang ditampilkan, ubah menjadi mengikuti
function getValueFromObservable() { return this.store } getValueFromObservable() .subscribe((data: any) => { // do something here with data console.log(data); });
solusi lainnya adalah ketika Anda membutuhkan data di dalam getValueFromObservable untuk mengembalikan penggunaan operator yang dapat diamati dan berlangganan fungsi.
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); });
sumber
Dalam dunia javascript single-threaded, asynchronous, promise-oriented, reactive-trending
async/await
adalah sahabat programmer imperatif-style:(async()=>{ const store = of("someValue"); function getValueFromObservable () { return store.toPromise(); } console.log(await getValueFromObservable()) })();
Dan dalam kasus
store
ini adalah urutan beberapa nilai: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); } })();
sumber
from(["someValue","someOtherValue"])
dengan observasi pilihan Anda yang memancarkan lebih dari satu nilai. Saya kira, mungkin lebih cocok digunakaninterval(1000)
.Cara yang layak adalah mengembalikan observable dari suatu fungsi dan berlangganan ke sana kapan pun diperlukan, karena observable itu malas, mereka akan mulai memancarkan nilai hanya ketika mereka berlangganan.
Di sini saya memiliki satu lagi solusi yang didorong oleh peristiwa yang menarik, yang awalnya saya gunakan untuk bermain-main. Contoh berikut melakukan ini dengan menggunakan modul " peristiwa " dari nodejs. Anda dapat menggunakannya dengan kerangka kerja lain di mana modul serupa ada ( Catatan : Sintaks dan gaya mungkin berubah tergantung pada modul yang digunakan).
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
Ini hanyalah sebuah contoh untuk menunjukkan sebuah ide dimana kita dapat mengirimkan data dari tempat yang berbeda dengan metode pemancaran dan pendengaran. Ini juga dikenal sebagai kode yang digerakkan oleh peristiwa.
sumber