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

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

本文关键字:观察 对象 一个 获取 另一个 事件      更新时间:2023-09-26

假设我有两个流。

  • buttonPresses

每当一个值改变时,我在我的价值流中得到这个值。

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

我想做一些事情,当我得到一个事件在buttonpressed流,在值流中的最新值。进行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);

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