2

I am working on a search bar which calls an API when user starts typing. One each key stroke, there is a request to server and it returns the response.

I want to reject previous promises before making the new call to the server, how can I achieve that? Right now I have the issue of old promises coming back and changing the UI which makes it to flicker.

export const makeGetPlaceData = (axios, uri) => (name, country) => {
  const promise = new Promise((resolve, reject) => {
    axios.get(`${uri}?name=${name}&country=${country}`)
      .then(response => {
        setTimeout(() => resolve(response), 2000);
      })
      .catch(error => {
        console.log('rejected', error);
          reject(error);
      });

    });

    return promise;
};

using setTimeout to simulate a slow network response.

jsan
  • 177
  • 1
  • 2
  • 14
  • you could simply store your pending requests and [cancel](https://github.com/axios/axios#cancellation) them before making a new one – Logar Mar 15 '18 at 14:57
  • I think you cant reject promise forcefully , check this out for more details - https://stackoverflow.com/questions/30233302/promise-is-it-possible-to-force-cancel-a-promise – Naga Sai A Mar 15 '18 at 14:59
  • @NagaSaiA but you can cancel an axios request, which would cause to enter the catch clause, in which you can call reject – Logar Mar 15 '18 at 15:02
  • Yop, `xhr` is abortable. But `promise` is not. – choz Mar 15 '18 at 15:06
  • The bluebird promise library does appear to have a cancel function: http://bluebirdjs.com/docs/api/cancellation.html, however I think a better implementation is either a wait between keystrokes or an id check much like @frodo2975 suggested below. – Phillip Thomas Mar 15 '18 at 15:14

1 Answers1

2

I generally do this at the handler level instead of the promise level. The gist of it is you keep track of how many calls you've done, and each callback knows its call number. When the promise resolves, if the callback is no longer the most recent, return early.

let lastCallId = 1;

function doCall() {
    var myCallId = lastCallId;
    lastCallId++;

    api.doSomething().then((data) => {
        if (myCallId !== lastCallId) return;

        // Do something with the data
    });
}
frodo2975
  • 10,340
  • 3
  • 34
  • 41