0

Note: Not a duplicate question of How to always run some code when a promise is fulfilled in Angular.js as that is specific to AngularJS.

I'm looking for something like jQuery's done or AngularJS's finally.

I have a promise that gets resolved or rejected. Whether it was resolved or rejected I'd like to run same function when fulfilled, as this:

var myPromise = new Promise(function(resolve, reject) {
    resolve('Success!');
    if( something ) {
        resolve('ok');
    } else {
        reject('not ok');
    }
});
myPromise.then(function(data) {
    var x = 1;
    var y = 2;
    console.log(data);
}, function(data) {
    var x = 1;
    var y = 2;
    console.log(data);
});

The above code works. The problem is I'm copying the same function twice. I know I could have a named function like this:

var myPromise = new Promise(function(resolve, reject) { ... });
myPromise.then(doWork, doWork);
function doWork(data) {
    var x = 1;
    var y = 2;
    console.log(data);
}

But I'm wondering if there's a way to:

  • Write the function once, instead of myPromise.then(doWork, doWork);, and..
  • Use anonymous function instead of named function. and..
Community
  • 1
  • 1
evilReiko
  • 19,501
  • 24
  • 86
  • 102

1 Answers1

5

In standard ES6 promises, just use the named function twice like in your second example. There is no finally in standard ES6.

The Bluebird promise library has a .finally() which would work well for you.

If you literally don't care if the promise is rejected, you can turn a rejection into a fulfill like this so that it always fulfills:

myPromise.catch(err => err).then(() => {
   // put your code here
});

You could also create a .finally() yourself:

if (!Promise.prototype.finally) {
    Promise.prototype.finally = function(fn) {
        return this.then(fn, fn);
    };
}

myPromise.finally(() => {
    // your code here
});

When using this, the returned promise (for further chaining) will take on the value from whatever your fn returns. If it returns a value, the promise will take on that value. If it returns a promise, the parent promise will follow that new promise. If it throws, the new promise will be rejected.

There are other implementations of .finally() that return a promise that always tracks the original parent promise so the state is not influenced by what happens in the .finally() callback. You did not ask for that extra feature here so I didn't show that slightly more complicated implementation, but you can see a proposed implementation like that here in section 14.2.

jfriend00
  • 683,504
  • 96
  • 985
  • 979