Подтвердить что ты не робот

Как вернуть значение из функции, в которой есть подписная подписка?

Я не знаю, как извлечь значение из 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())

Что я здесь делаю неправильно?

4b9b3361

Ответ 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
    );
  }