Как вернуть значение из функции, в которой есть подписная подписка?
Я не знаю, как извлечь значение из 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())
Что я здесь делаю неправильно?
Ответы
Ответ 1
Я понимаю, что этот Вопрос был довольно давно, и вы наверняка уже нашли правильное решение, но для всех, кто его ищет, я бы предложил решить его с помощью Обещания, чтобы сохранить асинхронную модель.
Более подробная версия создаст новое обещание:
function getValueFromObservable() {
return new Promise(resolve=>{
this.store
.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
})
Более тонкое решение будет использовать вместо этого функцию .toPromise() RxJS:
function getValueFromObservable() {
return this.store
.take(1)
.toPromise()
}
Принимающая сторона остается такой же, как указано выше, конечно.
Ответ 2
Это не совсем правильная идея использования 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
:
<div> {{ name }} </div>
Другой способ использования Observable
- через async
pipe http://briantroncone.com/?p=623
Примечание. Если это не то, о чем вы просите, обновите свой вопрос более подробно.
Ответ 3
Если вы хотите предварительно подписаться на тот же Observable, который будет возвращен, просто используйте
.do():
function getValueFromObservable() {
return this.store.do(
(data:any) => {
console.log("Line 1: " +data);
}
);
}
getValueFromObservable().subscribe(
(data:any) => {
console.log("Line 2: " +data)
}
);
Ответ 4
Проблема в том, что данные собираются внутри наблюдаемого, и я могу просто консоль записать его. Я хочу вернуть это значение и console.log или любой другой файл из другого файла, вызвав функцию, в которой он находится.
Похоже, вы ищете метод получения "текущего значения" внутри наблюдаемой, когда он излучает и после эмиссии.
Subject
и Observable
не имеют такой вещи. Когда значение передается, оно передается подписчикам, и с ним Observable
делается.
Вы можете использовать BehaviorSubject
, который хранит последнее переданное значение и сразу же отправляет его новым подписчикам.
Он также имеет метод getValue()
для получения текущего значения;
Дальнейшее чтение:
RxJS BehaviorSubject
Как получить текущее значение RxJS Subject или Observable?
Ответ 5
Наблюдаемые значения могут быть получены из любых мест. Исходная последовательность сначала нажимается на специальный наблюдатель, который способен излучать в другом месте. Это достигается с помощью Тема класса из 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');
Ответ 6
Например, это мой 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
);
}