0

I have a promise whose abstract code is something like:

const myPromise = (input) => new Promise((resolve, reject) => {
   //does something with input and provide some result
   if (everything_is_ok) resolve(result);
   else reject(error);
});

And this is the abstract flow of a procedure on my script:

let myVar;
//some code instructions...
myVar = something; //this comes as result of some code
if (condition){
    //(once promises resolves) compute function does something with pr_output
    //and provides another resulting output that gets stored on myVar for further computation
    myPromise(takes myVar or some data as input here).then((pr_output)=>{myVar=compute(pr_output);});
}
//further operations with myVar follow here...
//AND, if condition was true, I want/need to be sure that the promise has resolved
//and the computation in its "then" instruction ended as well before going on...

So now the question is: (How) is it possible to go on without having to call a subsequent function? I mean I know I could simply do something like:

if (condition){
    myPromise(takes myVar or some data as input here).then((pr_output)=>{myVar=compute(pr_output);
        anotherProcedure(myVar); // <== THIS IS IT
    });
} else anotherPocedure(myVar) // <== AND... THIS IS IT TOO

So I'd basically put every computation that comes after the condition check inside that anotherProcedure(myVar) and call it (providing myVar as input):

  • in the promise's then if condition was true
  • or in the else branch if condition was false

Is this the only way I can go or is it possible to avoid having to wrap the further computation inside that another procedure and call it that way? (If it is, please show me how to do it) Thank you

danicotra
  • 1,333
  • 2
  • 15
  • 34
  • 3
    You may want to take a look at [`async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) and [`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) – tevemadar Aug 04 '18 at 09:49
  • If `myPromise` does validation, why does it need to be asynchronous? – Bergi Aug 04 '18 at 12:51
  • 1
    If you just want to avoid *naming* the `anotherProcedure` function, have a look at [this question](https://stackoverflow.com/q/26599798/1048572). If you want to avoid having to write an (anonymous) function altogether, your only choice is `async`/`await`. – Bergi Aug 04 '18 at 12:53
  • Yeah, @tevemadar you're right (I had tried at first but had a bug and thought I was making some mistake in using `async/await` before realizing what was really wrong... +1 – danicotra Aug 04 '18 at 16:13
  • @Bergi you really must be the `promise` evangelist man :-D Thank you very much for linking that question in your comment, it looks very interesting to me +1 here and +1 there ...and thank you again! :-) – danicotra Aug 04 '18 at 16:19

2 Answers2

2

Create just one Promise chain, and you can tack on anotherPocedure(myVar) to the end of it. If the condition is true, then return the myPromise invocation (thus "pausing" the Promise chain until it resolves), else don't return anything (thus running the next .then which has anotherPocedure immediately). Translating your lower code, it could look like

Promise.resolve()
  .then(() => {
    if (condition) return myPromise(takes myVar or some data as input here)
      .then((pr_output) => {
         myVar = compute(pr_output);
      });
  })
  .then(() => anotherPocedure(myVar));

Though it would be more readable to extract the first .then into its own function, for better readability:

const tryCompute = () => {
  if (condition) return myPromise(takes myVar or some data as input here)
    .then((pr_output) => {
      myVar = compute(pr_output);
    });
  else return Promise.resolve();
};

tryCompute()
  .then(() => anotherPocedure(myVar));
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thank you for your reply, if I could I'd accept this one as well but I can only choose one and liked Jonas W. example very much... (Have my upvote, ofc.) – danicotra Aug 04 '18 at 16:09
1

As suggested in the comments you can simply use async / await:

 (async function() {
    if(condition) {
      const myVar = compute( await myPromise());
    }
    anotherProcedure();
 })();
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • I like this way to do it, thank you very much and sorry for my delay. I had tried something similar before asking but things seemed not to work and I thought I was doing something wrong with `async/await` ... After your reply, I ended up discovering a (very silly but hard to see) bug in the compute code *facepalm* :-p ... Thank you again, accepted. – danicotra Aug 04 '18 at 16:00