2

I am trying to create a new javascript Promise, and in function I pass to the new Promise(func) I would like to have access to the promise object I created to store and use later to resolve when something has occurred, rather than call functions to do the work from within the promise function.

I have tried:

let promise = new Promise((resolve, reject) => {
    this._setupPromise = { promise, resolve, reject };
});

But of course the "promise" variable is not yet set, so this._setupPromise.promise is undefined.

I can change it like this to add the promise to the object outside of the new Promise, but it just doesn't feel right since it could run before the Promise constructor function:

this._setupPromise = {};
let promise = new Promise((resolve, reject) => {
    this._setupPromise.resolve = resolve;
    this._setupPromise.reject = reject;
});
this._setupPromise.promise = promise

Is there any good solution to my delimma?

For anyone wondering why I would resolve/reject the Promise outside of calling it from within the Promise constructor function, I am optionally promisifying some legacy code, and to avoid a massive refactor of some existing use cases, it helps me resolve the promises elsewhere optionally.

John Morris
  • 543
  • 1
  • 4
  • 9
  • 3
    Your second code block is the only way to do it. If you described the overall problem you're trying to solve, we might be able to present a whole different approach to solving the actual problem, but for this particular approach, your second code block is your only choice. The promise itself is not defined until the executor has returned so you can't assign it to something until after. – jfriend00 Jan 16 '18 at 21:17
  • 1
    `since it could run before the Promise constructor function` - that's where you're mistaken – Jaromanda X Jan 16 '18 at 21:32
  • @JaromandaX So, will the Promise constructor function always run to completion first (synchronously)? If so my second code block where I store the promise reference in the object should be fine. – John Morris Jan 16 '18 at 21:35
  • the synchronous part will, as you have nothing asynchronous happening in there, you should be fine – Jaromanda X Jan 16 '18 at 21:36
  • @JohnMorris Do you want to save _setupPromise in a global scope so that you can access it easily from elewhere is it right? if so i think that you can transform your _setupPromise variable in a promise itself. – raythurnevoid Jan 16 '18 at 21:37
  • @JaromandaX Then I think that is my answer. If you want to make it the official answer I will accept it. Thanks! – John Morris Jan 16 '18 at 21:38
  • It's OK, jfriend said it in his comment, I was just clarifying where you made the erroneous assumption – Jaromanda X Jan 16 '18 at 21:41
  • I totally missed that jfriend confirned that at the end of his comment. Thanks. – John Morris Jan 16 '18 at 21:43

2 Answers2

2

Making my comment into an answer (and adding more explanation) since it actually was the answer you were looking for:

Your second code block is the way to do it. The promise variable itself does not have a value until the executor has returned and then the constructor has returned so you can't assign it to something else until after the executor and the promise constructor are done.

Since you don't have any asynchronous code inside the executor function, things will execute sequentially so this doesn't look like it would be a problem.

You may find that using a Deferred object (which just encapsulates the saving of the resolve and reject functions) as shown here is a bit cleaner and more reusable. Then, you could just do:

this._deferred = new Deferred();

And, later, you can do any of these:

this._deferred.resolve(...);
this._deferred.reject(...);
this._deferred.then(...);
this._deferred.catch(...);
let p = this._deferred.promise;

If you described the overall problem you're trying to solve, we might be able to present a whole different approach to solving the actual problem.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

Question was answered by jfriend00 and Jaramanda X in the comments. My second code block was the correct way to do this in my case because the function passed to the Promise constructor is executed before the Promise constructor exits.
That means in my case with no asynchronous code in the function, I can safely assign the promise reference afterwards.

John Morris
  • 543
  • 1
  • 4
  • 9