0

I've promise chain which the response in the first chain should be used later on in the chain (in 4 & 6) places, I use some global variable to handle it but this is not the right way ,there is a better way to achieve this with promise?

This is some illustration for the issue...

var step1 = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("This is step 1");
      resolve(20);
    }, ms);
  })
}
var step2 = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("This is step 2");
      resolve();
    }, ms);
  })
};
var step3 = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("This is step 3");
      resolve();
    }, ms);
  })
};

var step4 = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("Step 4, run : " + ms );
      resolve();
    }, ms);
  })
};


var globalVar = null;

//Promise chain
step1(500)
  .then((res) => {
     //Here I keep the response in global variable to use later on
     globalVar = res;
    log(res);
    return step2(300);
  }).then(() => {
    return step3(200);
  }).then(() =>{
   //Here I need to use the res from the first promise
    var lclvar = globalVar +200 ;
    return step4(lclvar);
  }).catch((err) => {
  log(err);
});

I found this but this is not helping in this case(at least didn't able to handle it)

How do I access previous promise results in a .then() chain?

Community
  • 1
  • 1
  • 1
    The question you found is exactly the one you need for your case. Please tell me what you did not understand about the answers, or which solution from one of the answers you chose and tried to apply. Please [edit] your question to show us what you tried (that didn't work)! Otherwise I'd have to close it as a duplicate. – Bergi Sep 26 '16 at 11:44
  • @Bergi -Thanks, I try to divide it without success...do you mean to use it like phil answer ? –  Sep 26 '16 at 12:01
  • Please post the code of that attempt nonetheless so that I can figure out what went wrong. If you already understood how dividing ("break the chain") is *supposed* to work, we'll be able to sort it out. – Bergi Sep 26 '16 at 12:07
  • Yes, the two answers here are fine, their approaches are described in the duplicate as "[Nesting (and) closures](http://stackoverflow.com/a/28250687/1048572)" and "[Explicit pass-through](http://stackoverflow.com/a/28250693/1048572)" – Bergi Sep 26 '16 at 12:08
  • @Bergi - The code in the post is exactly like my code in prod (just I'm calling to internal services in our company which will make all the post hard to understand...), if we able to solve it this will be great then I can use it in prod. –  Sep 26 '16 at 12:10
  • Yes, but you said the linked question "is not helping in this case". What exactly is the problem? Don't you understand how it corresponds to your problem? Did you choose one of the answers and tried to apply a solution but failed? – Bergi Sep 26 '16 at 12:12
  • @Bergi - Im working to adopt phil solution now,i'll update...thanks! –  Sep 26 '16 at 12:14
  • @Bergi - thanks I refactor my code and its working!, one question to verify and close this topic,assume that I use the globalVar inside function from my point of view this is still "global" and I should avoid using it like in the post since someone latter on in the function code can change it,is it valid assumption why it's better to use it like in phil answer? –  Sep 26 '16 at 18:49
  • Yes, [mutable variables makes everying more complicated](http://stackoverflow.com/a/28250700/1048572), and given that they are unnecessary in the light of better solutions they should be avoided here. In Phil's answer, all variables are constant. – Bergi Sep 26 '16 at 20:35

2 Answers2

1

You could just nest the step2, step3, etc calls inside the first handler, then res would be available to them all

step1(500).then((res) => {
  log(res);
  return step2(300)
    .then(() => step3(200))
    .then(() => step4(res + 200));
}).catch((err) => {
  log(err);
});
Phil
  • 157,677
  • 23
  • 242
  • 245
  • Thanks, But nesting promise is not a bad practise ? –  Sep 26 '16 at 11:58
  • 1
    @JennyM No, it's totally fine, especially when you need it (like here). You just must not forget to `return` the inner promise so that the outer chain can continue. – Bergi Sep 26 '16 at 12:09
0

If you really wan to chain this actually words. the idea is a bus parameter traveling along the way.It's created in the first promise as a closure.

you can run this code:

log=console.log
var step1 = (ms) => {
var Buss={p1:20};   
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("This is step 1");
      resolve(Buss);
    }, ms);
  })
}
var step2 = (ms,bus) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("This is step 2");
      resolve(bus);
    }, ms);
  })
};
var step3 = (ms,bus) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("This is step 3");
      resolve(bus);
    }, ms);
  })
};

var step4 = (bus) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      log("Step 4, run : " + bus.p1 );
      log("bus arrives:",bus);
      resolve(bus);
    }, bus.p1);
  })
};




//Promise chain
step1(500)
  .then((res) => {
     //Here I keep the response in global variable to use later on
     //globalVar = res;
    log(res);
    return step2(300,res);
  }).then((res) => {
    return step3(200,res);
  }).then((res) =>{
   //Here I need to use the res from the first promise
    //var lclvar = globalVar +200 ;
    res.p1+=200;
    return step4(res);
  }).catch((err) => {
  log(err);
});
O_Z
  • 1,515
  • 9
  • 11