当前位置:网站首页>A trap used by combinelatest and a debouncetime based solution

A trap used by combinelatest and a debouncetime based solution

2022-07-04 15:58:00 JerryWang_ Wang Zixi

First understand combineLatest What this operator does :

Multiple combinations Observable To create a Observable, Its value is based on each of its inputs Observable Calculated from the latest value of .

The marble diagram is shown in the figure below :

We have a limit value stream and an offset value stream . We use combineLatest Combine these flows to create a flow , The stream will have a new value every time one of the source streams changes . And then we use switchMap According to these values, get data from the back end to get pokemon$. Because we used switchMap, If a call is not over , So when a new call changes limit perhaps offset To initiate a new call , The previous call will be cancelled .

The code is as follows :

this.pokemon$ = combineLatest(limit$, offset$)
       .pipe(
        map(data => ({limit: data[0], offset: data[1]})),
        switchMap(data => this.pokemonService.getPokemon(data.limit, data.offset)),
        map((response: {results: Pokemon[]}) => response.results),
      );

The code address is as follows :

https://stackblitz.com/edit/a...

When I modified limit and offset After other values , Click on reset Button , At this point, it will be observed that two requests have been initiated , And the first request is automatically cancel The situation of :

By clicking the reset button , We update our two source streams by resetting the limit and offset values at the same time . The effect of this action is combineLatest The created flow triggered twice , Therefore, two back-end requests are initiated , On the other hand , Because we used switchMap, Immediately cancelled a .

Let's disassemble it in one step , To impress :

  • combineLatest Save the last value of all source streams . For example, the starting scene is ,limit = 8,offset = 2)
  • Click the reset button
  • limit Set to 5
  • combineLatest See a new value enter limit And send out a new combination ,limit = 5,offset = 2
  • switchMap Get these values and subscribe to the stream that triggers the back-end call
    The offset is set to 0
  • combineLatest See a new offset value , And send a new combination ,limit = 5,offset = 0
  • switchMap Get these values , Unsubscribe ( And therefore cancel ) Previous request and start a new request

What you may not expect in this process is , Whenever you set limit , This change will be changed in offset Spread directly to combineLatest.

How to avoid this behavior

If there is a way to ensure that changes occur in the same call stack ( This is what happens when you click the reset button ) Discarded to support the last change , We can solve our problems .

It means , When combineLatest When two values are issued in the same call stack , When the call stack is cleared , The last value will be sent .

So , We can do it in combineLatest After that, the direct utilization value is 0 Of debounceTime. This will ensure that only the last value is passed to switchMap, And after the call stack is cleared .

Whenever it comes to “ In the same call stack ” when , Can be replaced by “ Changes that occur in the same round of the event cycle ”.

Combined with the debounceTime(0) Then the sequence diagram :

  • combineLatest Save the last value of all source streams , The starting scene is ,limit = 8,offset = 2
  • Click the reset button
  • The limit is set to 5
  • combineLatest Operator sees a new value enter limit And send out a new combination ,limit = 5,offset = 2
  • debounceTime Operator sees a new value , also ( Because the value of the operator is 0) Will wait until the call stack is cleared to pass it
  • The offset is set to 0
  • combineLatest Operator sees a new offset value , And send a new combination ,limit = 5,offset = 0
  • debounceTime Operator sees a new value again , Old values will be discarded , And wait for the stack to be cleared to pass it
  • The call stack is cleared
  • debounceTime Operator does not see the new value , By combining ,limit = 5,offset = 0 Send data downstream
  • switchMap The operator takes these values and subscribes to the stream that triggers the back-end call

The fix code is very simple , Just add a line of code :

debounceTime(0),

The effect after repair , Click on reset After the button , For once HTTP The request was made :

more Jerry The original article of , All in :" Wang Zixi ":

原网站

版权声明
本文为[JerryWang_ Wang Zixi]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202141211409046.html