I have been using ES6 Promise.
Ordinarily, a Promise is constructed and used like this
new Promise(function(resolve, reject){
if (someCondition){
resolve();
} else {
reject();
}
});
But I have been doing something like below to take the resolve outside for the sake of flexibility.
var outsideResolve;
var outsideReject;
new Promise(function(resolve, reject) {
outsideResolve = resolve;
outsideReject = reject;
});
And later
onClick = function(){
outsideResolve();
}
This works fine, but is there an easier way to do this? If not, is this a good practice?
A solution I came up with in 2015 for my framework. I called this type of promises Task
I wrote a small lib for this. https://www.npmjs.com/package/@inf3rno/promise.exposed
I used the factory method approach others wrote, but I overrode the
then
,catch
,finally
methods too, so you can resolve the original promise by those as well.Resolving Promise without executor from outside:
Racing with the executor's setTimeout from outside:
There is a no-conflict mode if you don't want to pollute the global namespace:
I liked @JonJaques answer but I wanted to take it a step further.
If you bind
then
andcatch
then theDeferred
object, then it fully implements thePromise
API and you can treat it as promise andawait
it and such.I'm using a helper function to create what I call a "flat promise" -
And I'm using it like so -
See full working example -
Edit: I have created an NPM package called flat-promise and the code is also available on GitHub.
No, there is no other way to do this - the only thing I can say is that this use case isn't very common. Like Felix said in the comment - what you do will consistently work.
It's worth mentioning that the reason the promise constructor behaves this way is throw safety - if an exception you did not anticipate happens while your code is running inside the promise constructor it will turn into a rejection, this form of throw safety - converting thrown errors to rejections is important and helps maintain predictable code.
For this throw safety reason, the promise constructor was chosen over deferreds (which are an alternative promise construction way that do allow what you're doing) - as for best practices - I'd pass the element and use the promise constructor instead:
For this reason - whenever you can use the promise constructor over exporting the functions - I recommend you do use it. Whenever you can avoid both - avoid both and chain.
Note, that you should never use the promise constructor for things like
if(condition)
, the first example could be written as:A helper method would alleviate this extra overhead, and give you the same jQuery feel.
Usage would be
Which is similar to jQuery
Although, in a use case this simple, native syntax is fine