Noitidart
Noitidart

Reputation: 37308

Promise.defer standard?

I was working with Promises and prefer to use it like this:

function Deferred() {
    this.resolve = null;
    this.reject = null;
    this.promise = new Promise(function(resolve, reject) {
        this.resolve = resolve;
        this.reject = reject;
    }.bind(this));
    Object.freeze(this);
}

function somethingAsync() {

    var deferred = new Deferred();

    // do stuff then deferred.resolve();

    return deferred.promise;
}

I just came across though in Firefox Promise.defer() which gives me the same thing, is this standard? Or just specific to Firefox? I can't find it in the Promise docs of Firefox even - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Upvotes: 3

Views: 563

Answers (2)

htho
htho

Reputation: 1799

It is 2024 and all major browsers implement this. The function is Promise.withResolvers() - MDN

Your function would look like this:

function somethingAsync() {

    const { promise, resolve, reject } = Promise.withResolvers()

    // do stuff then resolve();

    return promise;
}

Be aware that this might lead to anti-patterns. The JS community has been working without this for a decade. Make sure you are comfortable with Promise-Chaining and async/await, before you jump right in to using this. (I know I wanted to use this, back when I learned how to use Promises, but then learned I could achieve better results without this.)

Upvotes: 1

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276506

Promise.defer was a suggestion at one point but it was decided to not include it in the spec but to instead include the promise constructor which uses the revealing constructor pattern.

It was implemented in Firefox and Chrome and later removed from Chrome. It is not a standard but was a proposal at one point.

Your usage of the promise constructor was explicitly supported as a use case when it was designed.

The reason the committee decided to go with the promise constructor was because it guards against synchronous throws by default:

new Promise((resolve, reject) => {
    thisThrowsSynchronously();
}); 

Had the promise constructor not done this - you would have to potentially .catch and } catch(e) { on every promise returning function invocation which can be frustrating. The promise constructor establishes an invariant where .catch is sufficient.

I'd also like to point out that outside of converting callback APIs - I can count the number of times I've used the promise constructor on one hand. Typically your code should have close to zero deferreds or usages of the promise constructor.

Upvotes: 5

Related Questions