Barguast Barguast - 10 days ago 4
Javascript Question

Creating a (ES6) promise without starting to resolve it

Using ES6 promises, how do I create a promise without defining the logic for resolving it? Here's a basic example (some TypeScript):

var promises = {};
function waitFor(key: string): Promise<any> {
if (key in promises) {
return promises[key];
}
var promise = new Promise(resolve => {
// But I don't want to try resolving anything here :(
});

promises[key] = promise;
return promise;
}

function resolveWith(key: string, value: any): void {
promises[key].resolve(value); // Not valid :(
}


It's easily done with other promise libraries. JQuery's for example:

var deferreds = {};
function waitFor(key: string): Promise<any> {
if (key in promises) {
return deferreds[key].promise();
}
var def = $.Deferred();
deferreds[key] = def;
return def.promise();
}

function resolveWith(key: string, value: any): void {
deferreds[key].resolve(value);
}


The only way I can see to do this would be to store the resolve function away somewhere within the promise's executor but that seems messy, and I'm not sure it's defined when exactly this function is run - is it always run immediately on construction?

Thanks.

Answer

Good question!

The resolver passed to the promise constructor intentionally runs synchronous in order to support this use case:

var deferreds = [];
var p = new Promise(function(resolve, reject){
    deferreds.push({resolve: resolve, reject: reject});
});

Then, at some later point in time:

 deferreds[0].resolve("Hello"); // resolve the promise with "Hello"

The reason the promise constructor is given is that:

  • Typically (but not always) resolution logic is bound to the creation.
  • The promise constructor is throw safe and converts exceptions to rejections.

Sometimes it doesn't fit and for that it the resolver runs synchronously. Here is related reading on the topic.

Comments