Resolve Javascript Promise outside function scope
up vote
174
down vote
favorite
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?
javascript promise es6-promise
add a comment |
up vote
174
down vote
favorite
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?
javascript promise es6-promise
1
I don't think there is another way. I believe it is specified that the callback passed toPromise
has to be executed synchronously to allow "exporting" the two functions.
– Felix Kling
Oct 1 '14 at 20:44
1
This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40
1
I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47
Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02
add a comment |
up vote
174
down vote
favorite
up vote
174
down vote
favorite
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?
javascript promise es6-promise
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?
javascript promise es6-promise
javascript promise es6-promise
edited Jun 29 '17 at 19:13
asked Oct 1 '14 at 20:40
Morio
2,13131625
2,13131625
1
I don't think there is another way. I believe it is specified that the callback passed toPromise
has to be executed synchronously to allow "exporting" the two functions.
– Felix Kling
Oct 1 '14 at 20:44
1
This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40
1
I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47
Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02
add a comment |
1
I don't think there is another way. I believe it is specified that the callback passed toPromise
has to be executed synchronously to allow "exporting" the two functions.
– Felix Kling
Oct 1 '14 at 20:44
1
This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40
1
I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47
Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02
1
1
I don't think there is another way. I believe it is specified that the callback passed to
Promise
has to be executed synchronously to allow "exporting" the two functions.– Felix Kling
Oct 1 '14 at 20:44
I don't think there is another way. I believe it is specified that the callback passed to
Promise
has to be executed synchronously to allow "exporting" the two functions.– Felix Kling
Oct 1 '14 at 20:44
1
1
This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40
This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40
1
1
I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47
I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47
Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02
Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02
add a comment |
9 Answers
9
active
oldest
votes
up vote
53
down vote
accepted
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:
var p = new Promise(function(resolve, reject){
this.onclick = resolve;
}.bind(this));
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:
var p = Promise[(someCondition)?"resolve":"reject"]();
1
Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke aPromise
chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
– Domi
May 3 '15 at 13:17
1
@Domi check out q-connection and RxJS.
– Benjamin Gruenbaum
May 3 '15 at 14:09
Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
– Domi
May 3 '15 at 14:17
1
How could do I the same using fetch API?
– Vinod Sobale
Apr 20 '17 at 5:05
24
Not common? I end up needing it almost every project.
– Tomáš Zato
Jun 23 '17 at 15:24
|
show 3 more comments
up vote
80
down vote
simple:
var promiseResolve, promiseReject;
var promise = new Promise(function(resolve, reject){
promiseResolve = resolve;
promiseReject = reject;
});
promiseResolve();
1
@ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code callspromiseResolve()
. The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
– Jon Jaques
Jun 27 '16 at 20:30
2
@JonJaques I'm not sure if what you say is true. The code that callspromiseResolve()
will not throw an exception. You can define a.catch
on the constructor and no matter what code calls it, the constructor's.catch
will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
– carter
Jul 5 '16 at 22:26
Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
– Jon Jaques
Jul 6 '16 at 13:26
I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
– carter
Jul 12 '16 at 17:17
4
I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
– KalEl
May 11 '17 at 22:17
|
show 2 more comments
up vote
61
down vote
Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.
Naive Implementation:
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject)=> {
this.reject = reject
this.resolve = resolve
})
}
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(()=> {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(result => {
console.log(result) // 42
})
ES5 Version:
function Deferred() {
var self = this;
this.promise = new Promise(function(resolve, reject) {
self.reject = reject
self.resolve = resolve
})
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(function() {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(function(result) {
console.log(result) // 42
})
1
Do notice the lexical scoping here.
– Florrie
Feb 2 '16 at 20:45
There is no practical difference in whetherresolve|reject
are assigned lexically or throughbind
. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
– Jon Jaques
Jul 13 '16 at 0:08
Using a deferred is the usual way to do this, I have no idea why this isn't higher
– BlueRaja - Danny Pflughoeft
Feb 28 '17 at 22:21
Excellent answer! Was looking for the deferred functionality that jQuery offers.
– Anshul Koka
Mar 28 '17 at 22:16
1
IsDeferred
deprecated?
– Pacerier
Oct 16 '17 at 1:34
|
show 1 more comment
up vote
12
down vote
A solution I came up with in 2015 for my framework. I called this type of promises Task
function createPromise(handler){
var _resolve, _reject;
var promise = new Promise(function(resolve, reject){
_resolve = resolve;
_reject = reject;
handler(resolve, reject);
})
promise.resolve = _resolve;
promise.reject = _reject;
return promise;
}
var promise = createPromise()
promise.then(function(data){ alert(data) })
promise.resolve(200) // resolve from outside
add a comment |
up vote
7
down vote
I liked @JonJaques answer but I wanted to take it a step further.
If you bind then
and catch
then the Deferred
object, then it fully implements the Promise
API and you can treat it as promise and await
it and such.
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
deferred.resolve('whoa!');
}, 2000);
async function someAsyncFunction() {
const value = await deferred;
console.log(value);
}
someAsyncFunction();
add a comment |
up vote
5
down vote
A helper method would alleviate this extra overhead, and give you the same jQuery feel.
function Deferred() {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
Usage would be
const { promise, resolve, reject } = Deferred();
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
return promise;
Which is similar to jQuery
const dfd = $.Deferred();
displayConfirmationDialog({
confirm: dfd.resolve,
cancel: dfd.reject
});
return dfd.promise();
Although, in a use case this simple, native syntax is fine
return new Promise((resolve, reject) => {
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
});
add a comment |
up vote
2
down vote
Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.
Here is the pattern:
function getPromise() {
var _resolve, _reject;
var promise = new Promise((resolve, reject) => {
_reject = reject;
_resolve = resolve;
});
promise.resolve_ex = (value) => {
_resolve(value);
};
promise.reject_ex = (value) => {
_reject(value);
};
return promise;
}
And using it:
var promise = getPromise();
promise.then(value => {
console.info('The promise has been fulfilled: ' + value);
});
promise.resolve_ex('hello');
// or the reject version
//promise.reject_ex('goodbye');
2
Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
– mike rodent
Jul 3 '17 at 18:05
> A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
– Steven Spungin
Jul 3 '17 at 20:12
yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to gopromise.resolve_ex = _resolve; promise.reject_ex = _reject;
... still works fine.
– mike rodent
Jul 3 '17 at 21:03
"attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
– Bergi
Jul 4 '17 at 16:41
2
The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
– Steven Spungin
Jul 4 '17 at 20:46
add a comment |
up vote
0
down vote
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:
const promise = Promise.exposed().then(console.log);
promise.resolve("This should show up in the console.");
Racing with the executor's setTimeout from outside:
const promise = Promise.exposed(function (resolve, reject){
setTimeout(function (){
resolve("I almost fell asleep.")
}, 100000);
}).then(console.log);
setTimeout(function (){
promise.resolve("I don't want to wait that much.");
}, 100);
There is a no-conflict mode if you don't want to pollute the global namespace:
const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
const promise = createExposedPromise().then(console.log);
promise.resolve("This should show up in the console.");
add a comment |
up vote
0
down vote
I'm using a helper function to create what I call a "flat promise" -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
And I'm using it like so -
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
See full working example -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
(async function run() {
const result = await doSomethingAsync()
.catch(err => console.error('rejected with', err));
console.log(result);
})();
Edit:
I have created an NPM package called flat-promise and the code is also available on GitHub.
add a comment |
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
53
down vote
accepted
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:
var p = new Promise(function(resolve, reject){
this.onclick = resolve;
}.bind(this));
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:
var p = Promise[(someCondition)?"resolve":"reject"]();
1
Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke aPromise
chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
– Domi
May 3 '15 at 13:17
1
@Domi check out q-connection and RxJS.
– Benjamin Gruenbaum
May 3 '15 at 14:09
Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
– Domi
May 3 '15 at 14:17
1
How could do I the same using fetch API?
– Vinod Sobale
Apr 20 '17 at 5:05
24
Not common? I end up needing it almost every project.
– Tomáš Zato
Jun 23 '17 at 15:24
|
show 3 more comments
up vote
53
down vote
accepted
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:
var p = new Promise(function(resolve, reject){
this.onclick = resolve;
}.bind(this));
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:
var p = Promise[(someCondition)?"resolve":"reject"]();
1
Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke aPromise
chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
– Domi
May 3 '15 at 13:17
1
@Domi check out q-connection and RxJS.
– Benjamin Gruenbaum
May 3 '15 at 14:09
Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
– Domi
May 3 '15 at 14:17
1
How could do I the same using fetch API?
– Vinod Sobale
Apr 20 '17 at 5:05
24
Not common? I end up needing it almost every project.
– Tomáš Zato
Jun 23 '17 at 15:24
|
show 3 more comments
up vote
53
down vote
accepted
up vote
53
down vote
accepted
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:
var p = new Promise(function(resolve, reject){
this.onclick = resolve;
}.bind(this));
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:
var p = Promise[(someCondition)?"resolve":"reject"]();
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:
var p = new Promise(function(resolve, reject){
this.onclick = resolve;
}.bind(this));
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:
var p = Promise[(someCondition)?"resolve":"reject"]();
answered Oct 1 '14 at 20:53
Benjamin Gruenbaum
183k62397433
183k62397433
1
Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke aPromise
chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
– Domi
May 3 '15 at 13:17
1
@Domi check out q-connection and RxJS.
– Benjamin Gruenbaum
May 3 '15 at 14:09
Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
– Domi
May 3 '15 at 14:17
1
How could do I the same using fetch API?
– Vinod Sobale
Apr 20 '17 at 5:05
24
Not common? I end up needing it almost every project.
– Tomáš Zato
Jun 23 '17 at 15:24
|
show 3 more comments
1
Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke aPromise
chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).
– Domi
May 3 '15 at 13:17
1
@Domi check out q-connection and RxJS.
– Benjamin Gruenbaum
May 3 '15 at 14:09
Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
– Domi
May 3 '15 at 14:17
1
How could do I the same using fetch API?
– Vinod Sobale
Apr 20 '17 at 5:05
24
Not common? I end up needing it almost every project.
– Tomáš Zato
Jun 23 '17 at 15:24
1
1
Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a
Promise
chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).– Domi
May 3 '15 at 13:17
Hi Benjamin! Is there currently no better way of getting yummy promise sugar if we don't know when the promise will be fulfilled yet? Like some sort of asynchronous wait/notify pattern? Like for example, "store", and later invoke a
Promise
chain? E.g. in my particular case, I am on a server, waiting for a specific client reply (a SYN-ACK-kinda hand-shake to make sure the client successfully updated state).– Domi
May 3 '15 at 13:17
1
1
@Domi check out q-connection and RxJS.
– Benjamin Gruenbaum
May 3 '15 at 14:09
@Domi check out q-connection and RxJS.
– Benjamin Gruenbaum
May 3 '15 at 14:09
Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
– Domi
May 3 '15 at 14:17
Hah, as usual, I was too impatient to wait! Either way, it seems like what those libraries are doing is overkill for my particular use-case, unless they are fixing issues that I have overlooked. Mind taking a look at my minimal solution?
– Domi
May 3 '15 at 14:17
1
1
How could do I the same using fetch API?
– Vinod Sobale
Apr 20 '17 at 5:05
How could do I the same using fetch API?
– Vinod Sobale
Apr 20 '17 at 5:05
24
24
Not common? I end up needing it almost every project.
– Tomáš Zato
Jun 23 '17 at 15:24
Not common? I end up needing it almost every project.
– Tomáš Zato
Jun 23 '17 at 15:24
|
show 3 more comments
up vote
80
down vote
simple:
var promiseResolve, promiseReject;
var promise = new Promise(function(resolve, reject){
promiseResolve = resolve;
promiseReject = reject;
});
promiseResolve();
1
@ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code callspromiseResolve()
. The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
– Jon Jaques
Jun 27 '16 at 20:30
2
@JonJaques I'm not sure if what you say is true. The code that callspromiseResolve()
will not throw an exception. You can define a.catch
on the constructor and no matter what code calls it, the constructor's.catch
will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
– carter
Jul 5 '16 at 22:26
Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
– Jon Jaques
Jul 6 '16 at 13:26
I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
– carter
Jul 12 '16 at 17:17
4
I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
– KalEl
May 11 '17 at 22:17
|
show 2 more comments
up vote
80
down vote
simple:
var promiseResolve, promiseReject;
var promise = new Promise(function(resolve, reject){
promiseResolve = resolve;
promiseReject = reject;
});
promiseResolve();
1
@ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code callspromiseResolve()
. The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
– Jon Jaques
Jun 27 '16 at 20:30
2
@JonJaques I'm not sure if what you say is true. The code that callspromiseResolve()
will not throw an exception. You can define a.catch
on the constructor and no matter what code calls it, the constructor's.catch
will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
– carter
Jul 5 '16 at 22:26
Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
– Jon Jaques
Jul 6 '16 at 13:26
I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
– carter
Jul 12 '16 at 17:17
4
I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
– KalEl
May 11 '17 at 22:17
|
show 2 more comments
up vote
80
down vote
up vote
80
down vote
simple:
var promiseResolve, promiseReject;
var promise = new Promise(function(resolve, reject){
promiseResolve = resolve;
promiseReject = reject;
});
promiseResolve();
simple:
var promiseResolve, promiseReject;
var promise = new Promise(function(resolve, reject){
promiseResolve = resolve;
promiseReject = reject;
});
promiseResolve();
answered Mar 17 '16 at 21:44
carter
2,54632037
2,54632037
1
@ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code callspromiseResolve()
. The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
– Jon Jaques
Jun 27 '16 at 20:30
2
@JonJaques I'm not sure if what you say is true. The code that callspromiseResolve()
will not throw an exception. You can define a.catch
on the constructor and no matter what code calls it, the constructor's.catch
will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
– carter
Jul 5 '16 at 22:26
Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
– Jon Jaques
Jul 6 '16 at 13:26
I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
– carter
Jul 12 '16 at 17:17
4
I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
– KalEl
May 11 '17 at 22:17
|
show 2 more comments
1
@ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code callspromiseResolve()
. The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.
– Jon Jaques
Jun 27 '16 at 20:30
2
@JonJaques I'm not sure if what you say is true. The code that callspromiseResolve()
will not throw an exception. You can define a.catch
on the constructor and no matter what code calls it, the constructor's.catch
will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console
– carter
Jul 5 '16 at 22:26
Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
– Jon Jaques
Jul 6 '16 at 13:26
I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
– carter
Jul 12 '16 at 17:17
4
I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
– KalEl
May 11 '17 at 22:17
1
1
@ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls
promiseResolve()
. The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.– Jon Jaques
Jun 27 '16 at 20:30
@ruX, As the accepted answer mentions - it was designed this way on purpose. The point is that if an exception is thrown it will be caught by the promise constructor. This answer (as well as mine) has the pitfall of possibly throwing an exception for whatever code calls
promiseResolve()
. The semantics of a promise are that it always returns a value. Also this is functionally the same as OP's post, I don't get what problem this is solving in a reusable way.– Jon Jaques
Jun 27 '16 at 20:30
2
2
@JonJaques I'm not sure if what you say is true. The code that calls
promiseResolve()
will not throw an exception. You can define a .catch
on the constructor and no matter what code calls it, the constructor's .catch
will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console– carter
Jul 5 '16 at 22:26
@JonJaques I'm not sure if what you say is true. The code that calls
promiseResolve()
will not throw an exception. You can define a .catch
on the constructor and no matter what code calls it, the constructor's .catch
will be called. Here is the jsbin demonstrating how this works: jsbin.com/yicerewivo/edit?js,console– carter
Jul 5 '16 at 22:26
Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
– Jon Jaques
Jul 6 '16 at 13:26
Yeah, it's caught because you wrapped another promise constructor around it - Exactly the point I'm trying to make. However, lets say you have some other code that's trying to call resolve() outside of the constructor (aka Deferred object)... It could throw an exception and not be caught jsbin.com/cokiqiwapo/1/edit?js,console
– Jon Jaques
Jul 6 '16 at 13:26
I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
– carter
Jul 12 '16 at 17:17
I see what you mean now, but I don't see how that relates to creating flexible promise resolvers. If you throw an error outside of something that can catch it, then it doesn't get caught. This is not a pitfall of a promise pattern. This is just an example of a bad pattern.
– carter
Jul 12 '16 at 17:17
4
4
I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
– KalEl
May 11 '17 at 22:17
I am not even sure it is a bad design. An error thrown outside the promise isn't supposed to be caught within the promise. It is perhaps an example of misconception or bad understanding, if the designer actually expects the error to be caught within.
– KalEl
May 11 '17 at 22:17
|
show 2 more comments
up vote
61
down vote
Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.
Naive Implementation:
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject)=> {
this.reject = reject
this.resolve = resolve
})
}
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(()=> {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(result => {
console.log(result) // 42
})
ES5 Version:
function Deferred() {
var self = this;
this.promise = new Promise(function(resolve, reject) {
self.reject = reject
self.resolve = resolve
})
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(function() {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(function(result) {
console.log(result) // 42
})
1
Do notice the lexical scoping here.
– Florrie
Feb 2 '16 at 20:45
There is no practical difference in whetherresolve|reject
are assigned lexically or throughbind
. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
– Jon Jaques
Jul 13 '16 at 0:08
Using a deferred is the usual way to do this, I have no idea why this isn't higher
– BlueRaja - Danny Pflughoeft
Feb 28 '17 at 22:21
Excellent answer! Was looking for the deferred functionality that jQuery offers.
– Anshul Koka
Mar 28 '17 at 22:16
1
IsDeferred
deprecated?
– Pacerier
Oct 16 '17 at 1:34
|
show 1 more comment
up vote
61
down vote
Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.
Naive Implementation:
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject)=> {
this.reject = reject
this.resolve = resolve
})
}
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(()=> {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(result => {
console.log(result) // 42
})
ES5 Version:
function Deferred() {
var self = this;
this.promise = new Promise(function(resolve, reject) {
self.reject = reject
self.resolve = resolve
})
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(function() {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(function(result) {
console.log(result) // 42
})
1
Do notice the lexical scoping here.
– Florrie
Feb 2 '16 at 20:45
There is no practical difference in whetherresolve|reject
are assigned lexically or throughbind
. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
– Jon Jaques
Jul 13 '16 at 0:08
Using a deferred is the usual way to do this, I have no idea why this isn't higher
– BlueRaja - Danny Pflughoeft
Feb 28 '17 at 22:21
Excellent answer! Was looking for the deferred functionality that jQuery offers.
– Anshul Koka
Mar 28 '17 at 22:16
1
IsDeferred
deprecated?
– Pacerier
Oct 16 '17 at 1:34
|
show 1 more comment
up vote
61
down vote
up vote
61
down vote
Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.
Naive Implementation:
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject)=> {
this.reject = reject
this.resolve = resolve
})
}
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(()=> {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(result => {
console.log(result) // 42
})
ES5 Version:
function Deferred() {
var self = this;
this.promise = new Promise(function(resolve, reject) {
self.reject = reject
self.resolve = resolve
})
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(function() {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(function(result) {
console.log(result) // 42
})
Bit late to the party here, but another way to do it would be to use a Deferred object. You essentially have the same amount of boilerplate, but it's handy if you want to pass them around and possibly resolve outside of their definition.
Naive Implementation:
class Deferred {
constructor() {
this.promise = new Promise((resolve, reject)=> {
this.reject = reject
this.resolve = resolve
})
}
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(()=> {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(result => {
console.log(result) // 42
})
ES5 Version:
function Deferred() {
var self = this;
this.promise = new Promise(function(resolve, reject) {
self.reject = reject
self.resolve = resolve
})
}
function asyncAction() {
var dfd = new Deferred()
setTimeout(function() {
dfd.resolve(42)
}, 500)
return dfd.promise
}
asyncAction().then(function(result) {
console.log(result) // 42
})
edited Jun 27 '16 at 20:35
answered Jan 6 '16 at 16:02
Jon Jaques
2,9791722
2,9791722
1
Do notice the lexical scoping here.
– Florrie
Feb 2 '16 at 20:45
There is no practical difference in whetherresolve|reject
are assigned lexically or throughbind
. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
– Jon Jaques
Jul 13 '16 at 0:08
Using a deferred is the usual way to do this, I have no idea why this isn't higher
– BlueRaja - Danny Pflughoeft
Feb 28 '17 at 22:21
Excellent answer! Was looking for the deferred functionality that jQuery offers.
– Anshul Koka
Mar 28 '17 at 22:16
1
IsDeferred
deprecated?
– Pacerier
Oct 16 '17 at 1:34
|
show 1 more comment
1
Do notice the lexical scoping here.
– Florrie
Feb 2 '16 at 20:45
There is no practical difference in whetherresolve|reject
are assigned lexically or throughbind
. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.
– Jon Jaques
Jul 13 '16 at 0:08
Using a deferred is the usual way to do this, I have no idea why this isn't higher
– BlueRaja - Danny Pflughoeft
Feb 28 '17 at 22:21
Excellent answer! Was looking for the deferred functionality that jQuery offers.
– Anshul Koka
Mar 28 '17 at 22:16
1
IsDeferred
deprecated?
– Pacerier
Oct 16 '17 at 1:34
1
1
Do notice the lexical scoping here.
– Florrie
Feb 2 '16 at 20:45
Do notice the lexical scoping here.
– Florrie
Feb 2 '16 at 20:45
There is no practical difference in whether
resolve|reject
are assigned lexically or through bind
. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.– Jon Jaques
Jul 13 '16 at 0:08
There is no practical difference in whether
resolve|reject
are assigned lexically or through bind
. This is just a simple implementation of the jQuery Deferred object that has been around since 1.0(ish). It works exactly like a promise, except there is no throw safety. The whole point of this question was how to save a few lines of code when creating promises.– Jon Jaques
Jul 13 '16 at 0:08
Using a deferred is the usual way to do this, I have no idea why this isn't higher
– BlueRaja - Danny Pflughoeft
Feb 28 '17 at 22:21
Using a deferred is the usual way to do this, I have no idea why this isn't higher
– BlueRaja - Danny Pflughoeft
Feb 28 '17 at 22:21
Excellent answer! Was looking for the deferred functionality that jQuery offers.
– Anshul Koka
Mar 28 '17 at 22:16
Excellent answer! Was looking for the deferred functionality that jQuery offers.
– Anshul Koka
Mar 28 '17 at 22:16
1
1
Is
Deferred
deprecated?– Pacerier
Oct 16 '17 at 1:34
Is
Deferred
deprecated?– Pacerier
Oct 16 '17 at 1:34
|
show 1 more comment
up vote
12
down vote
A solution I came up with in 2015 for my framework. I called this type of promises Task
function createPromise(handler){
var _resolve, _reject;
var promise = new Promise(function(resolve, reject){
_resolve = resolve;
_reject = reject;
handler(resolve, reject);
})
promise.resolve = _resolve;
promise.reject = _reject;
return promise;
}
var promise = createPromise()
promise.then(function(data){ alert(data) })
promise.resolve(200) // resolve from outside
add a comment |
up vote
12
down vote
A solution I came up with in 2015 for my framework. I called this type of promises Task
function createPromise(handler){
var _resolve, _reject;
var promise = new Promise(function(resolve, reject){
_resolve = resolve;
_reject = reject;
handler(resolve, reject);
})
promise.resolve = _resolve;
promise.reject = _reject;
return promise;
}
var promise = createPromise()
promise.then(function(data){ alert(data) })
promise.resolve(200) // resolve from outside
add a comment |
up vote
12
down vote
up vote
12
down vote
A solution I came up with in 2015 for my framework. I called this type of promises Task
function createPromise(handler){
var _resolve, _reject;
var promise = new Promise(function(resolve, reject){
_resolve = resolve;
_reject = reject;
handler(resolve, reject);
})
promise.resolve = _resolve;
promise.reject = _reject;
return promise;
}
var promise = createPromise()
promise.then(function(data){ alert(data) })
promise.resolve(200) // resolve from outside
A solution I came up with in 2015 for my framework. I called this type of promises Task
function createPromise(handler){
var _resolve, _reject;
var promise = new Promise(function(resolve, reject){
_resolve = resolve;
_reject = reject;
handler(resolve, reject);
})
promise.resolve = _resolve;
promise.reject = _reject;
return promise;
}
var promise = createPromise()
promise.then(function(data){ alert(data) })
promise.resolve(200) // resolve from outside
edited Apr 25 at 3:31


Boaz
14.7k74155
14.7k74155
answered Jul 28 '17 at 0:42
Maxmaxmaximus
1,1511313
1,1511313
add a comment |
add a comment |
up vote
7
down vote
I liked @JonJaques answer but I wanted to take it a step further.
If you bind then
and catch
then the Deferred
object, then it fully implements the Promise
API and you can treat it as promise and await
it and such.
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
deferred.resolve('whoa!');
}, 2000);
async function someAsyncFunction() {
const value = await deferred;
console.log(value);
}
someAsyncFunction();
add a comment |
up vote
7
down vote
I liked @JonJaques answer but I wanted to take it a step further.
If you bind then
and catch
then the Deferred
object, then it fully implements the Promise
API and you can treat it as promise and await
it and such.
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
deferred.resolve('whoa!');
}, 2000);
async function someAsyncFunction() {
const value = await deferred;
console.log(value);
}
someAsyncFunction();
add a comment |
up vote
7
down vote
up vote
7
down vote
I liked @JonJaques answer but I wanted to take it a step further.
If you bind then
and catch
then the Deferred
object, then it fully implements the Promise
API and you can treat it as promise and await
it and such.
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
deferred.resolve('whoa!');
}, 2000);
async function someAsyncFunction() {
const value = await deferred;
console.log(value);
}
someAsyncFunction();
I liked @JonJaques answer but I wanted to take it a step further.
If you bind then
and catch
then the Deferred
object, then it fully implements the Promise
API and you can treat it as promise and await
it and such.
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
deferred.resolve('whoa!');
}, 2000);
async function someAsyncFunction() {
const value = await deferred;
console.log(value);
}
someAsyncFunction();
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
deferred.resolve('whoa!');
}, 2000);
async function someAsyncFunction() {
const value = await deferred;
console.log(value);
}
someAsyncFunction();
class DeferredPromise {
constructor() {
this._promise = new Promise((resolve, reject) => {
// assign the resolve and reject functions to `this`
// making them usable on the class instance
this.resolve = resolve;
this.reject = reject;
});
// bind `then` and `catch` to implement the same interface as Promise
this.then = this._promise.then.bind(this._promise);
this.catch = this._promise.catch.bind(this._promise);
this[Symbol.toStringTag] = 'Promise';
}
}
const deferred = new DeferredPromise();
console.log('waiting 2 seconds...');
setTimeout(() => {
deferred.resolve('whoa!');
}, 2000);
async function someAsyncFunction() {
const value = await deferred;
console.log(value);
}
someAsyncFunction();
answered Nov 4 '17 at 15:13


Rico Kahler
4,31131931
4,31131931
add a comment |
add a comment |
up vote
5
down vote
A helper method would alleviate this extra overhead, and give you the same jQuery feel.
function Deferred() {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
Usage would be
const { promise, resolve, reject } = Deferred();
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
return promise;
Which is similar to jQuery
const dfd = $.Deferred();
displayConfirmationDialog({
confirm: dfd.resolve,
cancel: dfd.reject
});
return dfd.promise();
Although, in a use case this simple, native syntax is fine
return new Promise((resolve, reject) => {
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
});
add a comment |
up vote
5
down vote
A helper method would alleviate this extra overhead, and give you the same jQuery feel.
function Deferred() {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
Usage would be
const { promise, resolve, reject } = Deferred();
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
return promise;
Which is similar to jQuery
const dfd = $.Deferred();
displayConfirmationDialog({
confirm: dfd.resolve,
cancel: dfd.reject
});
return dfd.promise();
Although, in a use case this simple, native syntax is fine
return new Promise((resolve, reject) => {
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
});
add a comment |
up vote
5
down vote
up vote
5
down vote
A helper method would alleviate this extra overhead, and give you the same jQuery feel.
function Deferred() {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
Usage would be
const { promise, resolve, reject } = Deferred();
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
return promise;
Which is similar to jQuery
const dfd = $.Deferred();
displayConfirmationDialog({
confirm: dfd.resolve,
cancel: dfd.reject
});
return dfd.promise();
Although, in a use case this simple, native syntax is fine
return new Promise((resolve, reject) => {
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
});
A helper method would alleviate this extra overhead, and give you the same jQuery feel.
function Deferred() {
let resolve;
let reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
Usage would be
const { promise, resolve, reject } = Deferred();
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
return promise;
Which is similar to jQuery
const dfd = $.Deferred();
displayConfirmationDialog({
confirm: dfd.resolve,
cancel: dfd.reject
});
return dfd.promise();
Although, in a use case this simple, native syntax is fine
return new Promise((resolve, reject) => {
displayConfirmationDialog({
confirm: resolve,
cancel: reject
});
});
edited Feb 3 at 1:05
answered Feb 3 at 0:58


Cory Danielson
9,60023140
9,60023140
add a comment |
add a comment |
up vote
2
down vote
Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.
Here is the pattern:
function getPromise() {
var _resolve, _reject;
var promise = new Promise((resolve, reject) => {
_reject = reject;
_resolve = resolve;
});
promise.resolve_ex = (value) => {
_resolve(value);
};
promise.reject_ex = (value) => {
_reject(value);
};
return promise;
}
And using it:
var promise = getPromise();
promise.then(value => {
console.info('The promise has been fulfilled: ' + value);
});
promise.resolve_ex('hello');
// or the reject version
//promise.reject_ex('goodbye');
2
Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
– mike rodent
Jul 3 '17 at 18:05
> A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
– Steven Spungin
Jul 3 '17 at 20:12
yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to gopromise.resolve_ex = _resolve; promise.reject_ex = _reject;
... still works fine.
– mike rodent
Jul 3 '17 at 21:03
"attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
– Bergi
Jul 4 '17 at 16:41
2
The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
– Steven Spungin
Jul 4 '17 at 20:46
add a comment |
up vote
2
down vote
Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.
Here is the pattern:
function getPromise() {
var _resolve, _reject;
var promise = new Promise((resolve, reject) => {
_reject = reject;
_resolve = resolve;
});
promise.resolve_ex = (value) => {
_resolve(value);
};
promise.reject_ex = (value) => {
_reject(value);
};
return promise;
}
And using it:
var promise = getPromise();
promise.then(value => {
console.info('The promise has been fulfilled: ' + value);
});
promise.resolve_ex('hello');
// or the reject version
//promise.reject_ex('goodbye');
2
Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
– mike rodent
Jul 3 '17 at 18:05
> A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
– Steven Spungin
Jul 3 '17 at 20:12
yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to gopromise.resolve_ex = _resolve; promise.reject_ex = _reject;
... still works fine.
– mike rodent
Jul 3 '17 at 21:03
"attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
– Bergi
Jul 4 '17 at 16:41
2
The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
– Steven Spungin
Jul 4 '17 at 20:46
add a comment |
up vote
2
down vote
up vote
2
down vote
Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.
Here is the pattern:
function getPromise() {
var _resolve, _reject;
var promise = new Promise((resolve, reject) => {
_reject = reject;
_resolve = resolve;
});
promise.resolve_ex = (value) => {
_resolve(value);
};
promise.reject_ex = (value) => {
_reject(value);
};
return promise;
}
And using it:
var promise = getPromise();
promise.then(value => {
console.info('The promise has been fulfilled: ' + value);
});
promise.resolve_ex('hello');
// or the reject version
//promise.reject_ex('goodbye');
Our solution was to use closures to store the resolve/reject functions and additionally attach a function to extend the promise itself.
Here is the pattern:
function getPromise() {
var _resolve, _reject;
var promise = new Promise((resolve, reject) => {
_reject = reject;
_resolve = resolve;
});
promise.resolve_ex = (value) => {
_resolve(value);
};
promise.reject_ex = (value) => {
_reject(value);
};
return promise;
}
And using it:
var promise = getPromise();
promise.then(value => {
console.info('The promise has been fulfilled: ' + value);
});
promise.resolve_ex('hello');
// or the reject version
//promise.reject_ex('goodbye');
edited Jan 13 '17 at 13:02
answered Jan 12 '17 at 2:59
Steven Spungin
6,30322230
6,30322230
2
Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
– mike rodent
Jul 3 '17 at 18:05
> A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
– Steven Spungin
Jul 3 '17 at 20:12
yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to gopromise.resolve_ex = _resolve; promise.reject_ex = _reject;
... still works fine.
– mike rodent
Jul 3 '17 at 21:03
"attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
– Bergi
Jul 4 '17 at 16:41
2
The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
– Steven Spungin
Jul 4 '17 at 20:46
add a comment |
2
Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
– mike rodent
Jul 3 '17 at 18:05
> A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
– Steven Spungin
Jul 3 '17 at 20:12
yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to gopromise.resolve_ex = _resolve; promise.reject_ex = _reject;
... still works fine.
– mike rodent
Jul 3 '17 at 21:03
"attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
– Bergi
Jul 4 '17 at 16:41
2
The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
– Steven Spungin
Jul 4 '17 at 20:46
2
2
Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
– mike rodent
Jul 3 '17 at 18:05
Great... I'm just learning Promises but have been consistently puzzled by the fact that you don't appear to be able to resolve them "somewhere else". Using a closure to hide implementation details is a great idea... but in fact I'm not sure that's what you've done: rather than have "pseudo" private variables I'm pretty sure there's a way to completely conceal the variables which should be inaccessible... which is really what closures mean...
– mike rodent
Jul 3 '17 at 18:05
> A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
– Steven Spungin
Jul 3 '17 at 20:12
> A closure is a block of code that can be referenced (and passed around) with access to the variables of the enclosing scope. var _resolve, _reject; are the enclosing scope.
– Steven Spungin
Jul 3 '17 at 20:12
yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go
promise.resolve_ex = _resolve; promise.reject_ex = _reject;
... still works fine.– mike rodent
Jul 3 '17 at 21:03
yep, fair enough. Actually it seems to me that my answer is overcomplicating things, and furthermore that your answer can be simplified: you just need to go
promise.resolve_ex = _resolve; promise.reject_ex = _reject;
... still works fine.– mike rodent
Jul 3 '17 at 21:03
"attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
– Bergi
Jul 4 '17 at 16:41
"attach a function to extend the promise itself." - don't do that. Promises are result values, they should not provide the capability to resolve them. You don't want to pass those extended ones around.
– Bergi
Jul 4 '17 at 16:41
2
2
The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
– Steven Spungin
Jul 4 '17 at 20:46
The question was how to resolve it outside of the scope. Here is a solution that works, and in our production we have actually had a necessary reason to do it. I don't see why solving the problem stated deserves a downvote.
– Steven Spungin
Jul 4 '17 at 20:46
add a comment |
up vote
0
down vote
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:
const promise = Promise.exposed().then(console.log);
promise.resolve("This should show up in the console.");
Racing with the executor's setTimeout from outside:
const promise = Promise.exposed(function (resolve, reject){
setTimeout(function (){
resolve("I almost fell asleep.")
}, 100000);
}).then(console.log);
setTimeout(function (){
promise.resolve("I don't want to wait that much.");
}, 100);
There is a no-conflict mode if you don't want to pollute the global namespace:
const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
const promise = createExposedPromise().then(console.log);
promise.resolve("This should show up in the console.");
add a comment |
up vote
0
down vote
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:
const promise = Promise.exposed().then(console.log);
promise.resolve("This should show up in the console.");
Racing with the executor's setTimeout from outside:
const promise = Promise.exposed(function (resolve, reject){
setTimeout(function (){
resolve("I almost fell asleep.")
}, 100000);
}).then(console.log);
setTimeout(function (){
promise.resolve("I don't want to wait that much.");
}, 100);
There is a no-conflict mode if you don't want to pollute the global namespace:
const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
const promise = createExposedPromise().then(console.log);
promise.resolve("This should show up in the console.");
add a comment |
up vote
0
down vote
up vote
0
down vote
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:
const promise = Promise.exposed().then(console.log);
promise.resolve("This should show up in the console.");
Racing with the executor's setTimeout from outside:
const promise = Promise.exposed(function (resolve, reject){
setTimeout(function (){
resolve("I almost fell asleep.")
}, 100000);
}).then(console.log);
setTimeout(function (){
promise.resolve("I don't want to wait that much.");
}, 100);
There is a no-conflict mode if you don't want to pollute the global namespace:
const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
const promise = createExposedPromise().then(console.log);
promise.resolve("This should show up in the console.");
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:
const promise = Promise.exposed().then(console.log);
promise.resolve("This should show up in the console.");
Racing with the executor's setTimeout from outside:
const promise = Promise.exposed(function (resolve, reject){
setTimeout(function (){
resolve("I almost fell asleep.")
}, 100000);
}).then(console.log);
setTimeout(function (){
promise.resolve("I don't want to wait that much.");
}, 100);
There is a no-conflict mode if you don't want to pollute the global namespace:
const createExposedPromise = require("@inf3rno/promise.exposed/noConflict");
const promise = createExposedPromise().then(console.log);
promise.resolve("This should show up in the console.");
answered Oct 31 at 11:27


inf3rno
14.2k774124
14.2k774124
add a comment |
add a comment |
up vote
0
down vote
I'm using a helper function to create what I call a "flat promise" -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
And I'm using it like so -
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
See full working example -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
(async function run() {
const result = await doSomethingAsync()
.catch(err => console.error('rejected with', err));
console.log(result);
})();
Edit:
I have created an NPM package called flat-promise and the code is also available on GitHub.
add a comment |
up vote
0
down vote
I'm using a helper function to create what I call a "flat promise" -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
And I'm using it like so -
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
See full working example -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
(async function run() {
const result = await doSomethingAsync()
.catch(err => console.error('rejected with', err));
console.log(result);
})();
Edit:
I have created an NPM package called flat-promise and the code is also available on GitHub.
add a comment |
up vote
0
down vote
up vote
0
down vote
I'm using a helper function to create what I call a "flat promise" -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
And I'm using it like so -
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
See full working example -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
(async function run() {
const result = await doSomethingAsync()
.catch(err => console.error('rejected with', err));
console.log(result);
})();
Edit:
I have created an NPM package called flat-promise and the code is also available on GitHub.
I'm using a helper function to create what I call a "flat promise" -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
And I'm using it like so -
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
See full working example -
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
(async function run() {
const result = await doSomethingAsync()
.catch(err => console.error('rejected with', err));
console.log(result);
})();
Edit:
I have created an NPM package called flat-promise and the code is also available on GitHub.
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
(async function run() {
const result = await doSomethingAsync()
.catch(err => console.error('rejected with', err));
console.log(result);
})();
function flatPromise() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
function doSomethingAsync() {
// Get your promise and callbacks
const { resolve, reject, promise } = flatPromise();
// Do something amazing...
setTimeout(() => {
resolve('done!');
}, 500);
// Pass your promise to the world
return promise;
}
(async function run() {
const result = await doSomethingAsync()
.catch(err => console.error('rejected with', err));
console.log(result);
})();
edited yesterday
answered Nov 19 at 11:36
Arik
2,02311213
2,02311213
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f26150232%2fresolve-javascript-promise-outside-function-scope%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I don't think there is another way. I believe it is specified that the callback passed to
Promise
has to be executed synchronously to allow "exporting" the two functions.– Felix Kling
Oct 1 '14 at 20:44
1
This works for me exactly like you wrote it. So as far as I'm concerned, this is the "canonical" way.
– Gilad Barner
Jul 31 '16 at 8:40
1
I think there should be a formal way to achieve this in the future. This feature is very powerful in my opinion as you can wait for values from other contexts.
– Jose Nunez
Apr 3 at 12:47
Whenever they come up with a proper solution to this problem, I hope they will also make it work for nested promises, some of which may recur.
– Arthur Tarasov
Jul 5 at 8:02