1

Following is my scenario in which I am hitting a search API with search keyword but due to the uneven time its taking the UI is not updating correctly.

Scenario -

  1. I type a in an input box and search request goes like - search/?q=a and time its taking to resolve is 5sec.
  2. I keep on typing and now the query string is like - ab so another query goes like - search/?q=ab and assume its taking time of 4sec to get resolved.
  3. I keep on typing and now the query string is abc so another query goes like - search/?q=abc and assume its taking time to get resolved is 3sec.

So here you can see - Request 1 is getting the data in 5sec, 2 in 4 sec and 3rd in sec, so in UI the result is like -

a => /?q=a (5s)
ab => /?q=ab (4s)
abc => /?q=abc (3s)

Result in UI -

=> Result of abc
=> Result of abb
=> Result of a

But the correct order should be -

=> Result of a
=> Result of ab
=> Result of abc

My tries -

  1. I tried Promise.all. Problem is that it will update the UI only after 12 sec(5+4+3 sec).
  2. I tried Promise.allSettled() but problem is the array in which i am storing the promise is dynamic so I am not sure if this is I can enhance.

I believe this is not an edge case scenario and people might have faced it. Let me know what else I can try.

FYI - I also read about AbortController but it is clearly mentioned that its an experimental technology so I am bit hesitant in using this.

Nesh
  • 2,389
  • 7
  • 33
  • 54
  • One simple way is to let your searches working in any order you want, but include the search request in the search response, and only display the response which match the current value. In your scenario, results for a and ab search will be simply ignored. Other clue is to delay your search, in order to cancel a useless call when user is typing (with debounce, which has the same support than promise). – iguypouf Nov 25 '19 at 19:24
  • If it is order you are looking for, you want `Promise.each` or `async/await` – Prasanna Nov 25 '19 at 19:25
  • Generally you keep a reference to the last request issued. When a new search comes in cancel the existing request as you do not need that response any longer. Then issue the next request. See also https://stackoverflow.com/a/37492399/1260204 – Igor Nov 25 '19 at 19:46
  • Possible duplicate of [Promise - is it possible to force cancel a promise](https://stackoverflow.com/questions/30233302/promise-is-it-possible-to-force-cancel-a-promise) – Emile Bergeron Nov 25 '19 at 19:47

2 Answers2

1

there are several ways to do that at client side. the most common way I know is using debounce (from lodash)

  • using debounce, https://lodash.com/docs/4.17.15

    const loadData = (query) => {...}
    const debouncedLoadData = debounce(loadData, 200);
    
  • using setTimeout and clearTimeout.

some have lift up the concern about race and it is true. To make it perfectly then we need to implement cancellation for requests. So far, I can recommend using axios which has builting cancellation, https://github.com/axios/axios#cancellation

duc mai
  • 1,412
  • 2
  • 10
  • 17
0

In react you can use hooks , Please look at this working example