2016-07-10 1 views
28

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

Вы должны вернуться к заметному/Пообещайте и передайте данные через него, когда ваш наблюдаемый будет разрешен. – galvan

+1

Можете ли вы поместить для этого простой код? – Teddy

+4

То, что вы пытаетесь достичь, - это анти-шаблон: вы пытаетесь «синхронизировать» задачу async. Это не значит, что наблюдаемые должны работать. Короче говоря, в большинстве случаев функция, имеющая наблюдаемый в качестве входного сигнала, должна также возвращать наблюдаемое - или возвращать ничего. И когда вам нужно что-то сделать с выходом, подпишитесь на него. В этом случае, если вы хотите console.log данные, просто сделайте это внутри 'subscribe' –

ответ

7

Это не совсем правильная идея использования 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

Примечание: Если это не то, что вы просите, пожалуйста, обновите ваш вопрос более подробно

+0

Ну не совсем. Проблема в том, что данные захватываются внутри наблюдаемого, и я могу просто запустить его. Я хочу вернуть это значение и console.log или что угодно из другого файла, вызвав функцию, в которой он находится. – Teddy

+0

Андрей указал, как сделать «имя» доступным вне обратного вызова, назначив его переменной 'name' компонента. Невозможно возвращать 'name' синхронно в вашем случае. – Matt

+0

@Matt: Я не могу использовать его в 'Oninit', как это. Что делать, если мне нужно явно вернуться? Мой код вызова выглядит так: this.actions $ .ofType (SearchActions.SEARCH_MULTIPLE_NEW_QUERY) .map (toPayload) .fnWithMultipleAsyncReturns() ' – ishandutta2007

7

Я понимаю, что этот вопрос был довольно давно, и вы, безусловно, есть правильное решение сейчас, но для тех, кто ищет этот Я бы предложил решить его с обещанием сохранить асинхронный шаблон. Более подробная версия будет создавать новый посыл:

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

Наблюдаемые значения могут быть получены из любых мест. Первоначальная последовательность начинается с , толкает на специальный observer, который способен излучать в другом месте. Это достигается с помощью Тематический класс от 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 
    } 
}); 

Субъекты как Наблюдаемые и наблюдатели. Существуют и другие Subject types, такие как BehaviourSubject и ReplaySubject для других сценариев использования.

Не забудьте импортировать RxJS.

var Rx = require('rxjs'); 
5

Если вы хотите предварительно подписаться на ту же наблюдаемую, который будет возвращен, просто использовать

.Не():

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

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

Отличный ответ ... Он решил мою проблему в таких простой способ ..... +1 – Romesh

+0

Вы также можете использовать другие операторы, такие как '.map (data => data)', который делает то же самое, а затем подписывается там, где вы ожидаете результата –

 Смежные вопросы

  • Нет связанных вопросов^_^