Cancel a JavaScript Promise with Bluebird

There are various reasons why you would want to cancel a Promise. I am going to show you one specific situation which I have encountered recently.

In my case I had a page with a text input which allowed the user to filter a list in real-time, which was fetched from the back-end. The problem there was that because a new call was made at almost every keystroke, the results from the server were arriving back at almost the same time. In some cases the last promise to resolve was not for the last thing that the user has typed in, which was resulting in incorrect filtering.

Below is a simple example of how this can happen. We are not going to actually hit a server, but instead I have simulated network delays with setTimeout.

If you run the above code, you will see that result is “nr1”, even though the last thing that the user has typed in is “nr2”, and that’s what they see in the input box.

One way to solve this problem is to cancel the previous Promise every time we create a new one, inside filterInputHandler.

First of all, in order to be able to do that, we have to use Bluebird’s implementation of the Promise, which you can get from here http://bluebirdjs.com and require in your project. The example below is going to be for Bluebird 3.x, as in 2.x it is done differently.

Once you’ve got Bluebird, we have to configure it so that it allows cancellations, using Promise.config and then we can cancel any Promise with Promise.cancel().

Notice how we have configured Bluebird at lines 2–4 and then cancelled filterPromise at lines 26–28.

Bluebird also provides us with a isCancellable() method which is going to return a Boolean, letting us know whether the Promise can be cancelled.

Now running the second code snippet, the final value of result is going to be “nr2” — as expected. Try it out here https://jsfiddle.net/5x6gcqz1/.