Is there a “final” template for Promises?

Imagine the following example based on Promise:

function treadLightly() {
  return Promise.resolve()
    .then(function() { allocateResource(); })
    .then(function() { doRiskyOperation(); })
    .then(function() { releaseResource(); })
    .catch(function() { releaseResource(); })
  ;
}

We want to challenge releaseResource(), allow or reject doRiskyOperation(). But there is a smell of code smell when called releaseResource()in two different places.

What we really want is something equivalent to javascript finally.

Is there a cleaner way to code this in Promises?

+4
source share
3 answers

Although @TJ Crowder's Answer is correct, a practical solution to your problem may add one more .thenat the end:

function treadLightly() {
  return Promise.resolve()
    .then(function() { allocateResource(); })
    .then(function() { doRiskyOperation(); })
    .catch(function() { /* Do nothing, or log the error */ })
    .then(function() { releaseResource(); })
  ;
}
+3
source

ES2015 (ES6) promises finally . 2- , , ES2017 , , ES2018. ( finally) .

, Bluebird, Q when. jQuery promises always.

polyfill, :

if (typeof Promise !== 'function') {
    throw new TypeError('A global Promise is required');
}

if (typeof Promise.prototype.finally !== 'function') {
    var speciesConstructor = function (O, defaultConstructor) {
        var C = typeof O.constructor === 'undefined' ? defaultConstructor : O.constructor;
        var S = C[Symbol.species];
        return S == null ? defaultConstructor : S;

        var C = O.constructor;
        if (typeof C === 'undefined') {
            return defaultConstructor;
        }
        if (!C || (typeof C !== 'object' && typeof C !== 'function')) {
            throw new TypeError('O.constructor is not an Object');
        }
        var S = C[Symbol.species];
        if (S == null) {
            return defaultConstructor;
        }
        if (typeof S === 'function' && S.prototype) {
            return S;
        }
        throw new TypeError('no constructor found');
    };
    var shim = {
        finally(onFinally) {
            var handler = typeof onFinally === 'function' ? onFinally : () => {};
            var C;
            var newPromise = Promise.prototype.then.call(
                this, // throw if IsPromise(this) is not true
                x => new C(resolve => resolve(handler())).then(() => x),
                e => new C(resolve => resolve(handler())).then(() => { throw e; })
            );
            C = speciesConstructor(this, Promise); // throws if SpeciesConstructor throws
            return newPromise;
        }
    };
    Promise.prototype.finally = shim.finally;
}
+5

"finally" Promises?

(ES6) . Bluebird :

return new Promise((resolve, reject) => {
    ...
}).finally(() => {
    ...
});

. | Bluebird

+2

Source: https://habr.com/ru/post/1665128/


All Articles