Salman
Salman

Reputation: 9447

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?

Upvotes: 2

Views: 613

Answers (3)

sdgluck
sdgluck

Reputation: 27327

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();

Upvotes: 3

Qwertiy
Qwertiy

Reputation: 21440

You are doing a wrong thing.

return new Promise(function (resolve, reject) {
  this.req = request.get('/some.json')

Now promises returned from your function have the req property.

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

And promises created anywhere have abort function which uses req field.

You have to create your own class inhereted from promice and modify its prototype, but not the Promise prototype.

Upvotes: 0

Touffy
Touffy

Reputation: 6561

You've got a semantic issue here. A Promise is not the same thing as the thing that returns a Promise. In your case, the request is the thing you want to potentially abort.

If anything, the Promise represents the response, not the request. It makes no sense to cancel a response, does it?

What would make sense is if you have an object representing the request, with an abort() method, and calling that method would reject the related Promise.

Upvotes: 1

Related Questions