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.
I want to add my 2 cents here. Considering exactly the question "Creating a es6 Promise without starting resolve it" I solved it creating a wrapper function and calling the wrapper function instead. Code:
Let's say we have a function
f
which returns a PromiseNow, I want to prepare a call to
f('hello', 42)
without actually solving it:Hope this will help someone :)
Referencing
Promise.all()
as asked in the comments (and answered by @Joe Frambach), if I want to prepare a call tof1('super')
&f2('rainbow')
, 2 functions that return promisesGood question!
The resolver passed to the promise constructor intentionally runs synchronous in order to support this use case:
Then, at some later point in time:
The reason the promise constructor is given is that:
Sometimes it doesn't fit and for that it the resolver runs synchronously. Here is related reading on the topic.
How about a more comprehensive approach?
You could write a Constructor that returns a new Promise decorated with
.resolve()
and.reject()
methods.You would probably choose to name the constructor
Deferred
- a term with a lot of precedence in [the history of] javascript promises.By returning a decorated promsie rather than a plain object, all the promise's natural methods/properties remain available in addition to the decorations.
Also, by handling
fn
, the revealer pattern remains availble, should you need/choose to use it on a Deferred.DEMO
Now, with the
Deferred()
utility in place, your code is virtually identical to the jQuery example.