当事件发生在另一个可观察对象中时,从一个可观察对象中检索值

Retrieve values from one observable when an event happens in another observable

假设我有两个流。

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

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

当我在 buttonPresses 流中获得一个事件时,我想做一些事情,它具有值流中的最新值。例如拨打 API 电话。

但是,我不希望每次值更改时都发生一些事情。

我认为这是一个 "thinking in observables" 问题。这是我正在努力的实际代码。

/**
 * 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);

答案是使用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);