Stop what you're doing

Stop what you're doing

Rene Rubalcava | February 24, 2021

Can't Stop the Feeling

Once upon a time, there was a proposal in JavaScript to be able to cancel Promises. That didn't happen. Dojo Deferred was way ahead of its time here when it offered the ability cancel Promises, and other Promise libraries offered the same thing. But I would argue we live in a world of modern JavaScript, and you really shouldn't need a third-party Promise library. Observables like RxJS are a little different, as they have more to offer than just unsubscribing from things. But I tend to think you can get by just fine with native Promises for most use cases. So, how would you cancel a Promise using something like AbortSignal?

The bare bones could like something like this.

const controller = new AbortController();
const { signal } = controller;

const asyncMethod = (mySignal) => {
    return new Promise((resolve, reject) => {
        // do some stuff
        if (mySignal.aborted) {
            reject(new Error('Signal was aborted'));
        }
        else {
            resolve(result);
        }
    });
};

asyncMethod(signal);

// change your mind
controller.abort();

This is a really simplistic example, but gives you an idea about how it could be used.

Supported in the ArcGIS JSAPI

If you look at the documentation for the request in the ArcGIS JSAPI, you'll see that it has an option to pass a signal. This means you can cancel any requests you make. This signal can be passed in the options to any of the query methods in the API, like queryFeatures. That signal will get passed down to the request and if you abort the signal before the request is done, it will essentially cancel the request via a rejected Promise. The native fetch API also takes a signal that will reject if the signal is aborted.

const controller = new AbortController();
const { signal } = controller;

myLayer.queryFeatures(query, { signal })
    .then((handler)
    .catch(errorHandler);

controller.abort();

There could be various reasons you, as a developer might use this. Maybe there is some user interaction that updates charts in your app, and you want to limit some weird deferred loading of data if there is some interaction to update the chart during a request. Honestly, most developers probably don't have a need for this in their applications. But I think it's helpful to know the option is there if you ever do come across an occasion where you find you need this pattern. Consider it another tool on your belt.

Check out this video below for more details.