当事件发生在另一个observable中时,从一个observable中检索值

时间:2015-10-15 13:20:41

标签: javascript rxjs

假设我有两个流。

  • buttonPresses

每次值发生变化时,我都会在我的价值流中获得该值。

每次按下按钮,我都会在按钮流中收到一个事件。

我想在buttonPresses流中获取事件时执行某些操作,并在值流中使用最新值。例如进行API调用。

但是,每次值发生变化时,我都不希望发生任何事情。

我认为这是一个“可观察的思考”问题。这是我正在努力的实际代码。

/**
 * Provides a stream of POSTCODE_LOOKUP action events
 * @type {Object}
 */
export let PostcodeLookupActionsStream = Actions.stream
    .filter( action => action.key === KEYS.POSTCODE_LOOKUP );

/**
 * Provides a stream of values from a post code input field.
 * @type {Object}
 */
export let PostCodeValueStream = Actions.stream
    .filter( action => action.key === KEYS.POSTCODE_CHANGE )
    .map( action => action.payload.postcode )
    .shareReplay(1);

// Combine the two streams....?
export let PostCodeLookupStream = Rx.Observable
    .merge(PostCodeValueStream, PostcodeLookupActionsStream)
    .map( (value, action) => value);

/**
 * Provides a stream of address retrieved from a postcode lookup
 * @type {Array}
 */
export let AddressStream = PostCodeLookupStream
    .flatMapLatest( postcode =>  MyAPI.postcodeLookup( postcode ) )
    .flatMap( response => response.json() )
    .shareReplay(1);

1 个答案:

答案 0 :(得分:1)

答案是使用withLatestFrom。我不知道为什么花了这么长时间才在文档中找到它,但确实如此。

/**
 * Provides a stream of POSTCODE_LOOKUP events
 * e.g: A stream of postcodes.
 * @type {Object} a mouse event
 */
export let PostcodeLookupIntentsStream = Actions.stream
    .filter( action => action.key === KEYS.POSTCODE_LOOKUP );

/**
 * Provides a stream of values from a  post code input field
 * @type {String}
 */
export let PostCodeValueStream = Actions.stream
    .filter( action => action.key === KEYS.POSTCODE_CHANGE )
    .map( action => action.payload.postcode )
    .shareReplay(1);


/**
 * Combines `PostcodeLookupIntentsStream` and `PostCodeValueStream` to
 * produce a stream of postcode values. New postcode values are emitted
 * every time an event is emitted from the            
 * `PostcodeLookupIntentsStream`
 */
export let PostCodeLookupValueStream = PostcodeLookupIntentsStream
    .withLatestFrom( PostCodeValueStream, (action, value) => value  );


/**
 * Provides a stream of address retrieved from a postcode lookup
 * @type {Array}
 */
export let AddressStream = PostCodeLookupStream
    .flatMapLatest( postcode => return MyAPI.postcodeLookup( postcode ) )
    .flatMap( response => response.json() )
    .shareReplay(1);