0

The following situation:

function myFunction() {

      return new Promise(function (resolve, reject) {

          doSomething();
          let myVariable = doSomethingElse();

          let otherVariable = doOtherThings(myVariable);              

          return resolve(otherVariable);
      });
}

Now, I want myVariable not to initialized by a function call, but within a callback, or, rather, within a .then of a promise that is returned by an asynchronous function.

function myFunction() {

      return new Promise(function (resolve, reject) {

          doSomething();
          let myVariable;

          asynchronousFunctionThatReturnsPromise().then(function(param) {
             myVariable = doSomethingElse(param);
          });

          let otherVariable = doOtherThings(myVariable);              

          return resolve(otherVariable);
      });
}

Ideally the outer function would wait until myVariable is assigned a value, until it executes doOtherThings(myVariable), but I guess that is not possible within javascript.

Unfortunately, I cannot simply put all the following code in the "callback" function, since the outer functions return relies on the result.

Is there a way I can handle this, ideally without having to change anything on the outer function (myFunction)?

Lokomotywa
  • 2,624
  • 8
  • 44
  • 73
  • 1
    Put the code that relies on `myVariable` **inside** the `.then()` callback. That includes the `resolve()` call. Your `myFunction()` call already returns a Promise instance, so anything that calls it will have to use its own `.then()` callback anyway. – Pointy Sep 06 '18 at 20:24
  • 1
    Oh and you don't have to `return` the return value from `resolve()`. It won't hurt anything but it won't do anything useful either. – Pointy Sep 06 '18 at 20:24

1 Answers1

6

Get rid of the promise wrapper entirely. That's a promise anti-pattern to wrap one promise around another. Instead, just return the one you already have and put your logic inside the .then() handler:

function myFunction() {
        doSomething();

        return asynchronousFunctionThatReturnsPromise().then(function(param) {
           let myVariable = doSomethingElse(param);
           let otherVariable = doOtherThings(myVariable);              
           return otherVariable;
        });
    });
}

Usage:

myFunction().then(val => {
   console.log(val);        // will be the value of otherVariable above
}).catch(err => {
   console.log(err);
});

Unfortunately, I cannot simply put all the following code in the "callback" function, since the outer functions return relies on the result.

It's not clear what this means. You have to change the outer function in order to write myFunction() correctly.

Is there a way I can handle this, ideally without having to change anything on the outer function (myFunction)?

No. You should modify myFunction to write the code properly. If you have some real world situation with some real world constraints, then you'd have to post a different question with those actual details and real code (not pseudo code) for us to advise you more specifically.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • ah ok ok that makes sense – Pointy Sep 06 '18 at 20:28
  • well, myFunction is not supposed to return anything else than resolve(xyz), I dont't have access to where myFunction is called. – Lokomotywa Sep 06 '18 at 20:40
  • "No. You should modify myFunction to write the code properly" - Ok, that's what I wanted to know. – Lokomotywa Sep 06 '18 at 20:41
  • @Ferenjito - Your example returns a promise. My example returns a promise. They are the same to the caller, except that my example works properly in a number of cases that yours does not and my example avoids a common promise anti-pattern. – jfriend00 Sep 06 '18 at 20:41
  • Ah, OK, I got it. This promise stuff is really hard to grasp in the beginning. – Lokomotywa Sep 06 '18 at 20:43
  • 1
    @Ferenjito - It's also important to understand that one consequence of the promise anti-pattern you used is that if `asynchronousFunctionThatReturnsPromise()` rejects its promise, your code would silently ignore that rejection. The caller would never see a rejected promise because the promise you wrapped around `asynchronousFunctionThatReturnsPromise()` and are returning does not track the rejection which is a serious bug. That does not happen in my example. That's one of the main problems with using the anti-pattern (besides unnecessary added complexity). – jfriend00 Sep 06 '18 at 20:45
  • @Ferenjito - If this answered your question, you can indicate that to the community by clicking the checkmark to the left of the answer. If your question hasn't yet been answered, please indicate what else you need help with from your original question. – jfriend00 Sep 07 '18 at 17:24