Search code examples
javascriptpromisecancellationsuperagent

Create cancellable promise in ECMAScript 6


I am using native Promises for making ajax requests with superagent like this.

function callAPI() {
    return new Promise(function () {
        request.get('/some.json')
            .end(function (error, res) {
                resolve(res);
            });
    });
}

var reqProm = callAPI();

What I am wondering is, can I use this promise to cancel/abort the request made? I would think there should be a method in Promise.prototype like the following.

function callAPI() {
    new Promise(function (resolve, reject) {
        this.req = request.get('/some.json')
            .end(function (error, res) {
                resolve(res);
            });
    });
}

Promise.prototype.abort = function () {
 this.req.abort();
} 

However, I'm getting an error saying Promise.prototype is readonly. Is there any better way to do this?


Solution

  • I'm getting an error saying Promise.prototype is readonly

    I think this isn't true. What is the error you are receiving?

    What I am wondering is, can I use this promise to cancel/abort the request made?

    Instead of returning the new Promise you create, store it in a closure and return the Promise instance with an extra method that has scope to call the abort method on req and also the reject method of the Promise.

    As a side note, in your first example you are attempting to call resolve within your new Promise but are not making it available by accepting the resolve and reject functions as arguments to the Promise constructor executor.

    function callAPI() {
        let _reject;
        let _req;
    
        let promise = new Promise(function (resolve, reject) {
            _reject = reject;
            _req = request.get('/some.json').end(function (error, res) {
                resolve(res);
            });
        });
    
        promise.abort = function () {
            _req.abort();
            _reject();
        };
    
        return promise;
    }
    
    let call = callAPI();
    
    call.abort();