Search code examples
javascriptes6-promise

Rejecting a Promise before creating a new one


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.


Solution

  • 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
        });
    }