Я не знаю, как извлечь значение из Observable, которое будет возвращено функцией, в которой присутствует Observable. Мне нужно вернуть только его значение, ничего больше.
Текущая версия, которая работает
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
console.log(data)
}
)
}
getValueFromObservable()
Мне нужно, чтобы это работало, функция возвращала значение, а затем:
function getValueFromObservable() {
this.store.subscribe(
(data:any) => {
return data
}
)
}
console.log(getValueFromObservable())
Что я здесь делаю не так?
typescript
angular
rxjs
rxjs5
Тедди
источник
источник
subscribe
Ответы:
РЕДАКТИРОВАТЬ: обновленный код, чтобы отразить изменения, внесенные в способ работы каналов в более поздних версиях RXJS. Все операторы (возьмем мой пример) теперь заключены в оператор pipe ().
Я понимаю, что этот вопрос был довольно давно, и у вас наверняка есть подходящее решение, но для тех, кто ищет это, я бы предложил решить его с помощью обещания сохранить асинхронный шаблон.
Более подробная версия создаст новое обещание:
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() }
Принимающая сторона, конечно же, остается такой же, как и выше.
источник
getValueFromObservable
функции?Это не совсем правильная идея использования
Observable
В компоненте вы должны объявить член класса, который будет содержать объект (то, что вы собираетесь использовать в своем компоненте)
export class MyComponent { name: string = ""; }
Тогда a
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
:Другой способ использования
Observable
- черезasync
трубу http://briantroncone.com/?p=623Примечание . Если это не то, о чем вы спрашиваете, обновите свой вопрос, указав более подробную информацию.
источник
name
доступным вне обратного вызова, назначив егоname
переменной компонента . Вname
вашем случае возврат синхронно невозможен .Oninit
так, что, если мне нужно вернуть явно, мой код вызова выглядит такthis.actions$.ofType(SearchActions.SEARCH_MULTIPLE_NEW_QUERY).map(toPayload).fnWithMultipleAsyncReturns()
Если вы хотите предварительно подписаться на тот же Observable, который будет возвращен, просто используйте
function getValueFromObservable() { return this.store.do( (data:any) => { console.log("Line 1: " +data); } ); } getValueFromObservable().subscribe( (data:any) => { console.log("Line 2: " +data) } );
источник
.map(data => data)
который делает то же самое, а затем подписаться на него везде, где вы ожидаете результатаdo
теперь вызывается 6 ,tap
и вы должны использовать его в конвейере. Также обратите внимание, чтоtap
принимает несколько параметров для разных обработчиков, таких какnext
,complete
иerror
.Похоже, вы ищете геттер "текущего значения" внутри наблюдаемого, когда он испускает и после него.
Subject
иObservable
не имеет такого. Когда значение испускается, оно передается его подписчикам иObservable
ним завершается.Вы можете использовать
BehaviorSubject
который сохраняет последнее переданное значение и немедленно отправляет его новым подписчикам.У него также есть
getValue()
метод получения текущего значения;Дальнейшее чтение:
RxJS BehaviorSubject
Как получить текущее значение RxJS Subject или Observable?
источник
Наблюдаемые значения могут быть получены из любого места. Исходная последовательность сначала передается специальному наблюдателю, который может излучать где-то еще. Это достигается с помощью класса Subject из Reactive Extensions (RxJS).
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 } });
Субъектами являются и Наблюдатели, и Наблюдатели. Есть и другие типы тем такие как BehaviourSubject и ReplaySubject, для других сценариев использования.
Не забудьте импортировать RxJS.
var Rx = require('rxjs');
источник
Хотя предыдущие ответы могут работать в некотором роде, я думаю, что использование 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 ); }
источник
function getValueFromObservable() { this.store.subscribe( (data:any) => { return data } ) } console.log(getValueFromObservable())
В приведенном выше случае console.log запускается до того, как обещание будет разрешено, поэтому значение не отображается, измените его на следующее
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); });
источник
В однопоточном, асинхронном, ориентированном на обещание, реактивном мире javascript
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); } })();
источник
from(["someValue","someOtherValue"])
наблюдаемое по вашему выбору, которое испускает более одного значения. Думаю, это могло быть более подходящим для использованияinterval(1000)
.Достойным способом было бы вернуть наблюдаемый объект из функции и подписаться на него везде, где это необходимо, поскольку наблюдаемые объекты ленивы, они начнут выдавать значения только тогда, когда они подписаны.
Здесь у меня есть еще одно интересное решение, управляемое событиями, с которым я изначально экспериментировал. В следующем примере это делается с помощью модуля « событий » nodejs. Вы можете использовать его с другими фреймворками, где существует аналогичный модуль ( Примечание : синтаксис и стиль могут изменяться в зависимости от используемого модуля).
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
Это всего лишь пример, демонстрирующий идею, в которой мы можем передавать данные из разных мест методом испускания и прослушивания. Это также известно как код, управляемый событиями.
источник