Implementation of simple request chain logic with promises











up vote
1
down vote

favorite












I'm trying to implement dummy emulation of following logic:



enter image description here



But I'm not sure if I fully understand best practices of how to do it.
The main point of this task is to avoid triggering of redundant catch blocks callbacks. IMO if 1st request failed then all following code should stop.



I mean: if 1st request was failed, then we do not make 2nd request and do not call catch block of 2nd request promise.



In a few words I'm looking for very clean and simple solution like following:



firstRequest()
.then(r => {
console.log('firstRequest success', r);
return secondRequest();
}, e => console.log('firstRequest fail', e))
.then(r => {
console.log('secondRequest success', r);
// Should I return something here? Why?
}, e => console.log('secondRequest fail', e));


I've written following implementation. It works as expected in case of both requests are succeeded, and if 2nd request fails. But it works wrong if 1st request is failed (as you can see both catch block are triggering). You can play around with isFirstSucceed and isSecondSucceed flags to check it.






var ms = 1000;
var isFirstSucceed = false;
var isSecondSucceed = true;

var getUsersId = () => new Promise((res, rej) => {
console.log('request getUsersId');
setTimeout(() => {
if (isFirstSucceed) {
return res([1,2,3,4,5]);
} else {
return rej(new Error());
}
}, ms);
});

var getUserById = () => new Promise((res, rej) => {
console.log('request getUserById');
setTimeout(() => {
if (isSecondSucceed) {
return res({name: 'John'});
} else {
return rej(new Error());
}
}, ms);
});

getUsersId()
.then(r => {
console.info('1st request succeed', r);
return getUserById();
}, e => {
console.error('1st request failed', e);
throw e;
})
.then(
r => console.info('2nd request succeed', r),
e => {
console.error('2nd request failed', e);
throw e;
});





I can move then of 2nd request to then of 1st request but it looks ugly.






var ms = 1000;
var isFirstSucceed = false;
var isSecondSucceed = true;

var getUsersId = () => new Promise((res, rej) => {
console.log('request getUsersId');
setTimeout(() => {
if (isFirstSucceed) {
return res([1,2,3,4,5]);
} else {
return rej(new Error());
}
}, ms);
});

var getUserById = () => new Promise((res, rej) => {
console.log('request getUserById');
setTimeout(() => {
if (isSecondSucceed) {
return res({name: 'John'});
} else {
return rej(new Error());
}
}, ms);
});

getUsersId()
.then(r => {
console.info('1st request succeed', r);
getUserById().then(
r => console.info('2nd request succeed', r),
e => {
console.error('2nd request failed', e);
throw e;
});
}, e => {
console.error('1st request failed', e);
throw e;
})





Questions:




  • How to implement described logic according to all promises best practices?

  • Is it possible to avoid throw e in every catch block?

  • Should I use es6 Promises? Or it is better to use some promises library?

  • Any other advices?










share|improve this question




























    up vote
    1
    down vote

    favorite












    I'm trying to implement dummy emulation of following logic:



    enter image description here



    But I'm not sure if I fully understand best practices of how to do it.
    The main point of this task is to avoid triggering of redundant catch blocks callbacks. IMO if 1st request failed then all following code should stop.



    I mean: if 1st request was failed, then we do not make 2nd request and do not call catch block of 2nd request promise.



    In a few words I'm looking for very clean and simple solution like following:



    firstRequest()
    .then(r => {
    console.log('firstRequest success', r);
    return secondRequest();
    }, e => console.log('firstRequest fail', e))
    .then(r => {
    console.log('secondRequest success', r);
    // Should I return something here? Why?
    }, e => console.log('secondRequest fail', e));


    I've written following implementation. It works as expected in case of both requests are succeeded, and if 2nd request fails. But it works wrong if 1st request is failed (as you can see both catch block are triggering). You can play around with isFirstSucceed and isSecondSucceed flags to check it.






    var ms = 1000;
    var isFirstSucceed = false;
    var isSecondSucceed = true;

    var getUsersId = () => new Promise((res, rej) => {
    console.log('request getUsersId');
    setTimeout(() => {
    if (isFirstSucceed) {
    return res([1,2,3,4,5]);
    } else {
    return rej(new Error());
    }
    }, ms);
    });

    var getUserById = () => new Promise((res, rej) => {
    console.log('request getUserById');
    setTimeout(() => {
    if (isSecondSucceed) {
    return res({name: 'John'});
    } else {
    return rej(new Error());
    }
    }, ms);
    });

    getUsersId()
    .then(r => {
    console.info('1st request succeed', r);
    return getUserById();
    }, e => {
    console.error('1st request failed', e);
    throw e;
    })
    .then(
    r => console.info('2nd request succeed', r),
    e => {
    console.error('2nd request failed', e);
    throw e;
    });





    I can move then of 2nd request to then of 1st request but it looks ugly.






    var ms = 1000;
    var isFirstSucceed = false;
    var isSecondSucceed = true;

    var getUsersId = () => new Promise((res, rej) => {
    console.log('request getUsersId');
    setTimeout(() => {
    if (isFirstSucceed) {
    return res([1,2,3,4,5]);
    } else {
    return rej(new Error());
    }
    }, ms);
    });

    var getUserById = () => new Promise((res, rej) => {
    console.log('request getUserById');
    setTimeout(() => {
    if (isSecondSucceed) {
    return res({name: 'John'});
    } else {
    return rej(new Error());
    }
    }, ms);
    });

    getUsersId()
    .then(r => {
    console.info('1st request succeed', r);
    getUserById().then(
    r => console.info('2nd request succeed', r),
    e => {
    console.error('2nd request failed', e);
    throw e;
    });
    }, e => {
    console.error('1st request failed', e);
    throw e;
    })





    Questions:




    • How to implement described logic according to all promises best practices?

    • Is it possible to avoid throw e in every catch block?

    • Should I use es6 Promises? Or it is better to use some promises library?

    • Any other advices?










    share|improve this question


























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I'm trying to implement dummy emulation of following logic:



      enter image description here



      But I'm not sure if I fully understand best practices of how to do it.
      The main point of this task is to avoid triggering of redundant catch blocks callbacks. IMO if 1st request failed then all following code should stop.



      I mean: if 1st request was failed, then we do not make 2nd request and do not call catch block of 2nd request promise.



      In a few words I'm looking for very clean and simple solution like following:



      firstRequest()
      .then(r => {
      console.log('firstRequest success', r);
      return secondRequest();
      }, e => console.log('firstRequest fail', e))
      .then(r => {
      console.log('secondRequest success', r);
      // Should I return something here? Why?
      }, e => console.log('secondRequest fail', e));


      I've written following implementation. It works as expected in case of both requests are succeeded, and if 2nd request fails. But it works wrong if 1st request is failed (as you can see both catch block are triggering). You can play around with isFirstSucceed and isSecondSucceed flags to check it.






      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      return getUserById();
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })
      .then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });





      I can move then of 2nd request to then of 1st request but it looks ugly.






      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      getUserById().then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })





      Questions:




      • How to implement described logic according to all promises best practices?

      • Is it possible to avoid throw e in every catch block?

      • Should I use es6 Promises? Or it is better to use some promises library?

      • Any other advices?










      share|improve this question















      I'm trying to implement dummy emulation of following logic:



      enter image description here



      But I'm not sure if I fully understand best practices of how to do it.
      The main point of this task is to avoid triggering of redundant catch blocks callbacks. IMO if 1st request failed then all following code should stop.



      I mean: if 1st request was failed, then we do not make 2nd request and do not call catch block of 2nd request promise.



      In a few words I'm looking for very clean and simple solution like following:



      firstRequest()
      .then(r => {
      console.log('firstRequest success', r);
      return secondRequest();
      }, e => console.log('firstRequest fail', e))
      .then(r => {
      console.log('secondRequest success', r);
      // Should I return something here? Why?
      }, e => console.log('secondRequest fail', e));


      I've written following implementation. It works as expected in case of both requests are succeeded, and if 2nd request fails. But it works wrong if 1st request is failed (as you can see both catch block are triggering). You can play around with isFirstSucceed and isSecondSucceed flags to check it.






      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      return getUserById();
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })
      .then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });





      I can move then of 2nd request to then of 1st request but it looks ugly.






      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      getUserById().then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })





      Questions:




      • How to implement described logic according to all promises best practices?

      • Is it possible to avoid throw e in every catch block?

      • Should I use es6 Promises? Or it is better to use some promises library?

      • Any other advices?






      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      return getUserById();
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })
      .then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });





      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      return getUserById();
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })
      .then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });





      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      getUserById().then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })





      var ms = 1000;
      var isFirstSucceed = false;
      var isSecondSucceed = true;

      var getUsersId = () => new Promise((res, rej) => {
      console.log('request getUsersId');
      setTimeout(() => {
      if (isFirstSucceed) {
      return res([1,2,3,4,5]);
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      var getUserById = () => new Promise((res, rej) => {
      console.log('request getUserById');
      setTimeout(() => {
      if (isSecondSucceed) {
      return res({name: 'John'});
      } else {
      return rej(new Error());
      }
      }, ms);
      });

      getUsersId()
      .then(r => {
      console.info('1st request succeed', r);
      getUserById().then(
      r => console.info('2nd request succeed', r),
      e => {
      console.error('2nd request failed', e);
      throw e;
      });
      }, e => {
      console.error('1st request failed', e);
      throw e;
      })






      javascript promise es6-promise






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 27 at 15:23

























      asked Nov 22 at 15:54









      WebBrother

      567819




      567819
























          6 Answers
          6






          active

          oldest

          votes

















          up vote
          2
          down vote













          Your flow diagram is the logic you want to achieve, but it isn't quite how promises work. The issue is that there is no way to tell a promise chain to just "end" right here and don't call any other .then() or .catch() handlers later in the chain. If you get a reject in the chain and leave it rejected, it will call the next .catch() handler in the chain. If you handle the rejection locally and don't rethrow it, then it will call the next .then() handler in the chain. Neither of those options matches your logic diagram exactly.



          So, you have to mentally change how you think about your logic diagram so that you can use a promise chain.



          The simplest option (what is probably used for 90% of promise chains) is to just put one error handler at the end of the chain. Any error anywhere in the chain just skips to the single .catch() handler at the end of the chain. FYI, in most cases, I find the code more readable with .catch() than the 2nd argument to .then() so that's how I've shown it here



          firstRequest().then(secondRequest).then(r => {
          console.log('both requests successful');
          }).catch(err => {
          // An error from either request will show here
          console.log(err);
          });




          When you provide a catch block and you don't either return a rejected promise or rethrow the error, then the promise infrastructure thinks you have "handled" the promise so the chain continues as resolved. If you rethrow the error, then the next catch block will fire and any intervening .then() handlers will be skipped.



          You can make use of that to catch an error locally, do something (like log it) and then rethrow it to keep the promise chain as rejected.



          firstRequest().catch(e => {
          console.log('firstRequest fail', e));
          e.logged = true;
          throw e;
          }).then(r => {
          console.log('firstRequest success', r);
          return secondRequest();
          }).then(r => {
          console.log('secondRequest success', r);
          }).catch(e => {
          if (!e.logged) {
          console.log('secondRequest fail', e));
          }
          });


          Or, a version that marks the error object with a debug message and then rethrows and can then only logs errors in one place:



          firstRequest().catch(e => {
          e.debugMsg = 'firstRequest fail';
          throw e;
          }).then(r => {
          console.log('firstRequest success', r);
          return secondRequest().catch(e => {
          e.debugMsg = 'secondRequest fail';
          throw e;
          });
          }).then(r => {
          console.log('secondRequest success', r);
          }).catch(e => {
          console.log(e.debugMsg, e);
          });




          I've even had situations where a little helper function saved me some code and some visual complexity, particularly if there are a bunch of these in the chain:



          function markErr(debugMsg) {
          return function(e) {
          // mark the error object and rethrow
          e.debugMsg = debugMsg;
          throw e;
          }
          }

          firstRequest()
          .catch(markErr('firstRequest fail'))
          .then(r => {
          console.log('firstRequest success', r);
          return secondRequest().catch(markErr('secondRequest fail'));
          }).then(r => {
          console.log('secondRequest success', r);
          }).catch(e => {
          console.log(e.debugMsg, e);
          });


          Taking each of your questions individually:




          How to implement described logic according to all promises best practices?




          Described above. I'd say the simplest and best practice is the very first code block I show. If you need to make sure when you get to the final .catch() that you have a uniquely identifiable error so you know which step caused it, then modify the rejected error in each individual function to be unique so you can tell which it was from the one .catch() block at the end. If you can't modify those functions, then you can wrap them with a wrapper that catches and marks their error or you can do that inline with the markErr() type solution I showed. In most cases, you just need to know there was an error and not the exact step it occurred in so usually that isn't necessary for every step in the chain.




          Is it possible to avoid throw e in every catch block?




          That depends. If the error objects are already unique, then you can just use one .catch() at the end. If the error objects are not unique, but you need to know which exact step failed, then you have to either use a .catch() at each step so you can mark the error uniquely or you need to modify each function in the chain to have a unique error.




          Should I use es6 Promises?




          Yes. No better way I know of.




          Or it is better to use some promises library?




          I'm not aware of any features in a promise library that would make this simpler. This is really just about how you want to report errors and whether each step is defining a unique error or not. A promise library can't really do that for you.




          Any other advice?




          Keep learning more about how to mold promises into a solution for each individual problem.






          share|improve this answer






























            up vote
            1
            down vote













            IMO, you can use async/await... Still, with promises but is much cleaner to look at. Here is my sample approach on above logic.



            function firstRequest() {
            return new Promise((resolve, reject) => {
            // add async function here
            // and resolve("done")/reject("err")
            });
            }

            function secondRequest() {
            return new Promise((resolve, reject) => {
            // add async function here
            // and resolve("done")/reject("err")
            });
            }

            async function startProgram() {
            try {
            await firstRequest();
            await secondRequest();
            } catch(err) {
            console.log(err);
            goToEndFn();
            }
            }

            startProgram(); // start the program





            share|improve this answer























            • This doesn't really answer questions about how the OP logs and handles each individual error separately. This just throws all the errors into one spot which you can do just fine with a regular promise chain too with one .catch() at the end. I think the OP knows that. That isn't what their question is.
              – jfriend00
              Nov 22 at 16:59


















            up vote
            1
            down vote













            https://github.com/xobotyi/await-of



            $ npm i --save await-of 




            import of from "await-of";

            async () => {
            let [res1, err1] = await of(axios.get('some.uri/to/get11'));
            let [res2, err2] = await of(axios.get('some.uri/to/get22'));

            if (err1) {
            console.log('err1', err1)
            }
            if (err2) {
            console.log('err2', err2)
            }
            console.log('res1', res1)
            console.log('res2', res2)

            };





            share|improve this answer




























              up vote
              0
              down vote













              Async/await maybe?



              async function foo() {
              try {
              const firstResult = await firstRequest();
              const secondResult = await secondRequest();
              } catch(e) {
              // e = either first or second error
              }
              }


              In this code an error on the first request transfers control to the catch block and the second request won't start




              Should I use es6 Promises?




              Probably yes, until you're pretty sure your code will be used in obsolete environments. They are already not so new and flashy






              share|improve this answer




























                up vote
                0
                down vote













                you do not need handle error for every promise



                you need handle error only as common error



                do like this:



                var ms = 1000;
                var isFirstSucceed = false;
                var isSecondSucceed = true;

                var getUsersId = () => new Promise((res, rej) => {
                console.log('request getUsersId');
                setTimeout(() => {
                if (isFirstSucceed) {
                return res([1,2,3,4,5]);
                } else {
                return rej();
                }
                }, ms);
                });

                var getUserById = () => new Promise((res, rej) => {
                console.log('request getUserById');
                setTimeout(() => {
                if (isSecondSucceed) {
                return res({name: 'John'});
                } else {
                return rej(new Error());
                }
                }, ms);
                });

                getUsersId()
                .then(r => {
                console.info('1st request succeed', r);
                return getUserById();
                })
                .then(r => {
                console.info('2st request succeed', r);
                return;
                })
                .catch((e) => {
                console.error('request failed', e);
                throw new Error(e);
                })





                share|improve this answer





















                • Thanks, but you provided different logic. As I described I need do handling of every request fail. In your example all fails logic was putted to last catch block, but I want to split that logic to a few parts.
                  – WebBrother
                  Nov 22 at 16:24


















                up vote
                0
                down vote













                You can abuse duck-typing technique to stop promise chain with return { then: function() {} };. I modified your code just right after this line console.error('1st request failed', e);






                var ms = 1000;
                var isFirstSucceed = false;
                var isSecondSucceed = true;

                var getUsersId = () => new Promise((res, rej) => {
                console.log('request getUsersId');
                setTimeout(() => {
                if (isFirstSucceed) {
                return res([1,2,3,4,5]);
                } else {
                return rej(new Error());
                }
                }, ms);
                });

                var getUserById = () => new Promise((res, rej) => {
                console.log('request getUserById');
                setTimeout(() => {
                if (isSecondSucceed) {
                return res({name: 'John'});
                } else {
                return rej(new Error());
                }
                }, ms);
                });

                getUsersId()
                .then(r => {
                console.info('1st request succeed', r);
                return getUserById();
                }, e => {
                console.error('1st request failed', e);
                return { then: function() {} };
                })
                .then(
                r => console.info('2nd request succeed', r),
                e => {
                console.error('2nd request failed', e);
                throw e;
                });








                share|improve this answer























                  Your Answer






                  StackExchange.ifUsing("editor", function () {
                  StackExchange.using("externalEditor", function () {
                  StackExchange.using("snippets", function () {
                  StackExchange.snippets.init();
                  });
                  });
                  }, "code-snippets");

                  StackExchange.ready(function() {
                  var channelOptions = {
                  tags: "".split(" "),
                  id: "1"
                  };
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function() {
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled) {
                  StackExchange.using("snippets", function() {
                  createEditor();
                  });
                  }
                  else {
                  createEditor();
                  }
                  });

                  function createEditor() {
                  StackExchange.prepareEditor({
                  heartbeatType: 'answer',
                  autoActivateHeartbeat: false,
                  convertImagesToLinks: true,
                  noModals: true,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: 10,
                  bindNavPrevention: true,
                  postfix: "",
                  imageUploader: {
                  brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                  contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                  allowUrls: true
                  },
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  });


                  }
                  });














                  draft saved

                  draft discarded


















                  StackExchange.ready(
                  function () {
                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434539%2fimplementation-of-simple-request-chain-logic-with-promises%23new-answer', 'question_page');
                  }
                  );

                  Post as a guest















                  Required, but never shown

























                  6 Answers
                  6






                  active

                  oldest

                  votes








                  6 Answers
                  6






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes








                  up vote
                  2
                  down vote













                  Your flow diagram is the logic you want to achieve, but it isn't quite how promises work. The issue is that there is no way to tell a promise chain to just "end" right here and don't call any other .then() or .catch() handlers later in the chain. If you get a reject in the chain and leave it rejected, it will call the next .catch() handler in the chain. If you handle the rejection locally and don't rethrow it, then it will call the next .then() handler in the chain. Neither of those options matches your logic diagram exactly.



                  So, you have to mentally change how you think about your logic diagram so that you can use a promise chain.



                  The simplest option (what is probably used for 90% of promise chains) is to just put one error handler at the end of the chain. Any error anywhere in the chain just skips to the single .catch() handler at the end of the chain. FYI, in most cases, I find the code more readable with .catch() than the 2nd argument to .then() so that's how I've shown it here



                  firstRequest().then(secondRequest).then(r => {
                  console.log('both requests successful');
                  }).catch(err => {
                  // An error from either request will show here
                  console.log(err);
                  });




                  When you provide a catch block and you don't either return a rejected promise or rethrow the error, then the promise infrastructure thinks you have "handled" the promise so the chain continues as resolved. If you rethrow the error, then the next catch block will fire and any intervening .then() handlers will be skipped.



                  You can make use of that to catch an error locally, do something (like log it) and then rethrow it to keep the promise chain as rejected.



                  firstRequest().catch(e => {
                  console.log('firstRequest fail', e));
                  e.logged = true;
                  throw e;
                  }).then(r => {
                  console.log('firstRequest success', r);
                  return secondRequest();
                  }).then(r => {
                  console.log('secondRequest success', r);
                  }).catch(e => {
                  if (!e.logged) {
                  console.log('secondRequest fail', e));
                  }
                  });


                  Or, a version that marks the error object with a debug message and then rethrows and can then only logs errors in one place:



                  firstRequest().catch(e => {
                  e.debugMsg = 'firstRequest fail';
                  throw e;
                  }).then(r => {
                  console.log('firstRequest success', r);
                  return secondRequest().catch(e => {
                  e.debugMsg = 'secondRequest fail';
                  throw e;
                  });
                  }).then(r => {
                  console.log('secondRequest success', r);
                  }).catch(e => {
                  console.log(e.debugMsg, e);
                  });




                  I've even had situations where a little helper function saved me some code and some visual complexity, particularly if there are a bunch of these in the chain:



                  function markErr(debugMsg) {
                  return function(e) {
                  // mark the error object and rethrow
                  e.debugMsg = debugMsg;
                  throw e;
                  }
                  }

                  firstRequest()
                  .catch(markErr('firstRequest fail'))
                  .then(r => {
                  console.log('firstRequest success', r);
                  return secondRequest().catch(markErr('secondRequest fail'));
                  }).then(r => {
                  console.log('secondRequest success', r);
                  }).catch(e => {
                  console.log(e.debugMsg, e);
                  });


                  Taking each of your questions individually:




                  How to implement described logic according to all promises best practices?




                  Described above. I'd say the simplest and best practice is the very first code block I show. If you need to make sure when you get to the final .catch() that you have a uniquely identifiable error so you know which step caused it, then modify the rejected error in each individual function to be unique so you can tell which it was from the one .catch() block at the end. If you can't modify those functions, then you can wrap them with a wrapper that catches and marks their error or you can do that inline with the markErr() type solution I showed. In most cases, you just need to know there was an error and not the exact step it occurred in so usually that isn't necessary for every step in the chain.




                  Is it possible to avoid throw e in every catch block?




                  That depends. If the error objects are already unique, then you can just use one .catch() at the end. If the error objects are not unique, but you need to know which exact step failed, then you have to either use a .catch() at each step so you can mark the error uniquely or you need to modify each function in the chain to have a unique error.




                  Should I use es6 Promises?




                  Yes. No better way I know of.




                  Or it is better to use some promises library?




                  I'm not aware of any features in a promise library that would make this simpler. This is really just about how you want to report errors and whether each step is defining a unique error or not. A promise library can't really do that for you.




                  Any other advice?




                  Keep learning more about how to mold promises into a solution for each individual problem.






                  share|improve this answer



























                    up vote
                    2
                    down vote













                    Your flow diagram is the logic you want to achieve, but it isn't quite how promises work. The issue is that there is no way to tell a promise chain to just "end" right here and don't call any other .then() or .catch() handlers later in the chain. If you get a reject in the chain and leave it rejected, it will call the next .catch() handler in the chain. If you handle the rejection locally and don't rethrow it, then it will call the next .then() handler in the chain. Neither of those options matches your logic diagram exactly.



                    So, you have to mentally change how you think about your logic diagram so that you can use a promise chain.



                    The simplest option (what is probably used for 90% of promise chains) is to just put one error handler at the end of the chain. Any error anywhere in the chain just skips to the single .catch() handler at the end of the chain. FYI, in most cases, I find the code more readable with .catch() than the 2nd argument to .then() so that's how I've shown it here



                    firstRequest().then(secondRequest).then(r => {
                    console.log('both requests successful');
                    }).catch(err => {
                    // An error from either request will show here
                    console.log(err);
                    });




                    When you provide a catch block and you don't either return a rejected promise or rethrow the error, then the promise infrastructure thinks you have "handled" the promise so the chain continues as resolved. If you rethrow the error, then the next catch block will fire and any intervening .then() handlers will be skipped.



                    You can make use of that to catch an error locally, do something (like log it) and then rethrow it to keep the promise chain as rejected.



                    firstRequest().catch(e => {
                    console.log('firstRequest fail', e));
                    e.logged = true;
                    throw e;
                    }).then(r => {
                    console.log('firstRequest success', r);
                    return secondRequest();
                    }).then(r => {
                    console.log('secondRequest success', r);
                    }).catch(e => {
                    if (!e.logged) {
                    console.log('secondRequest fail', e));
                    }
                    });


                    Or, a version that marks the error object with a debug message and then rethrows and can then only logs errors in one place:



                    firstRequest().catch(e => {
                    e.debugMsg = 'firstRequest fail';
                    throw e;
                    }).then(r => {
                    console.log('firstRequest success', r);
                    return secondRequest().catch(e => {
                    e.debugMsg = 'secondRequest fail';
                    throw e;
                    });
                    }).then(r => {
                    console.log('secondRequest success', r);
                    }).catch(e => {
                    console.log(e.debugMsg, e);
                    });




                    I've even had situations where a little helper function saved me some code and some visual complexity, particularly if there are a bunch of these in the chain:



                    function markErr(debugMsg) {
                    return function(e) {
                    // mark the error object and rethrow
                    e.debugMsg = debugMsg;
                    throw e;
                    }
                    }

                    firstRequest()
                    .catch(markErr('firstRequest fail'))
                    .then(r => {
                    console.log('firstRequest success', r);
                    return secondRequest().catch(markErr('secondRequest fail'));
                    }).then(r => {
                    console.log('secondRequest success', r);
                    }).catch(e => {
                    console.log(e.debugMsg, e);
                    });


                    Taking each of your questions individually:




                    How to implement described logic according to all promises best practices?




                    Described above. I'd say the simplest and best practice is the very first code block I show. If you need to make sure when you get to the final .catch() that you have a uniquely identifiable error so you know which step caused it, then modify the rejected error in each individual function to be unique so you can tell which it was from the one .catch() block at the end. If you can't modify those functions, then you can wrap them with a wrapper that catches and marks their error or you can do that inline with the markErr() type solution I showed. In most cases, you just need to know there was an error and not the exact step it occurred in so usually that isn't necessary for every step in the chain.




                    Is it possible to avoid throw e in every catch block?




                    That depends. If the error objects are already unique, then you can just use one .catch() at the end. If the error objects are not unique, but you need to know which exact step failed, then you have to either use a .catch() at each step so you can mark the error uniquely or you need to modify each function in the chain to have a unique error.




                    Should I use es6 Promises?




                    Yes. No better way I know of.




                    Or it is better to use some promises library?




                    I'm not aware of any features in a promise library that would make this simpler. This is really just about how you want to report errors and whether each step is defining a unique error or not. A promise library can't really do that for you.




                    Any other advice?




                    Keep learning more about how to mold promises into a solution for each individual problem.






                    share|improve this answer

























                      up vote
                      2
                      down vote










                      up vote
                      2
                      down vote









                      Your flow diagram is the logic you want to achieve, but it isn't quite how promises work. The issue is that there is no way to tell a promise chain to just "end" right here and don't call any other .then() or .catch() handlers later in the chain. If you get a reject in the chain and leave it rejected, it will call the next .catch() handler in the chain. If you handle the rejection locally and don't rethrow it, then it will call the next .then() handler in the chain. Neither of those options matches your logic diagram exactly.



                      So, you have to mentally change how you think about your logic diagram so that you can use a promise chain.



                      The simplest option (what is probably used for 90% of promise chains) is to just put one error handler at the end of the chain. Any error anywhere in the chain just skips to the single .catch() handler at the end of the chain. FYI, in most cases, I find the code more readable with .catch() than the 2nd argument to .then() so that's how I've shown it here



                      firstRequest().then(secondRequest).then(r => {
                      console.log('both requests successful');
                      }).catch(err => {
                      // An error from either request will show here
                      console.log(err);
                      });




                      When you provide a catch block and you don't either return a rejected promise or rethrow the error, then the promise infrastructure thinks you have "handled" the promise so the chain continues as resolved. If you rethrow the error, then the next catch block will fire and any intervening .then() handlers will be skipped.



                      You can make use of that to catch an error locally, do something (like log it) and then rethrow it to keep the promise chain as rejected.



                      firstRequest().catch(e => {
                      console.log('firstRequest fail', e));
                      e.logged = true;
                      throw e;
                      }).then(r => {
                      console.log('firstRequest success', r);
                      return secondRequest();
                      }).then(r => {
                      console.log('secondRequest success', r);
                      }).catch(e => {
                      if (!e.logged) {
                      console.log('secondRequest fail', e));
                      }
                      });


                      Or, a version that marks the error object with a debug message and then rethrows and can then only logs errors in one place:



                      firstRequest().catch(e => {
                      e.debugMsg = 'firstRequest fail';
                      throw e;
                      }).then(r => {
                      console.log('firstRequest success', r);
                      return secondRequest().catch(e => {
                      e.debugMsg = 'secondRequest fail';
                      throw e;
                      });
                      }).then(r => {
                      console.log('secondRequest success', r);
                      }).catch(e => {
                      console.log(e.debugMsg, e);
                      });




                      I've even had situations where a little helper function saved me some code and some visual complexity, particularly if there are a bunch of these in the chain:



                      function markErr(debugMsg) {
                      return function(e) {
                      // mark the error object and rethrow
                      e.debugMsg = debugMsg;
                      throw e;
                      }
                      }

                      firstRequest()
                      .catch(markErr('firstRequest fail'))
                      .then(r => {
                      console.log('firstRequest success', r);
                      return secondRequest().catch(markErr('secondRequest fail'));
                      }).then(r => {
                      console.log('secondRequest success', r);
                      }).catch(e => {
                      console.log(e.debugMsg, e);
                      });


                      Taking each of your questions individually:




                      How to implement described logic according to all promises best practices?




                      Described above. I'd say the simplest and best practice is the very first code block I show. If you need to make sure when you get to the final .catch() that you have a uniquely identifiable error so you know which step caused it, then modify the rejected error in each individual function to be unique so you can tell which it was from the one .catch() block at the end. If you can't modify those functions, then you can wrap them with a wrapper that catches and marks their error or you can do that inline with the markErr() type solution I showed. In most cases, you just need to know there was an error and not the exact step it occurred in so usually that isn't necessary for every step in the chain.




                      Is it possible to avoid throw e in every catch block?




                      That depends. If the error objects are already unique, then you can just use one .catch() at the end. If the error objects are not unique, but you need to know which exact step failed, then you have to either use a .catch() at each step so you can mark the error uniquely or you need to modify each function in the chain to have a unique error.




                      Should I use es6 Promises?




                      Yes. No better way I know of.




                      Or it is better to use some promises library?




                      I'm not aware of any features in a promise library that would make this simpler. This is really just about how you want to report errors and whether each step is defining a unique error or not. A promise library can't really do that for you.




                      Any other advice?




                      Keep learning more about how to mold promises into a solution for each individual problem.






                      share|improve this answer














                      Your flow diagram is the logic you want to achieve, but it isn't quite how promises work. The issue is that there is no way to tell a promise chain to just "end" right here and don't call any other .then() or .catch() handlers later in the chain. If you get a reject in the chain and leave it rejected, it will call the next .catch() handler in the chain. If you handle the rejection locally and don't rethrow it, then it will call the next .then() handler in the chain. Neither of those options matches your logic diagram exactly.



                      So, you have to mentally change how you think about your logic diagram so that you can use a promise chain.



                      The simplest option (what is probably used for 90% of promise chains) is to just put one error handler at the end of the chain. Any error anywhere in the chain just skips to the single .catch() handler at the end of the chain. FYI, in most cases, I find the code more readable with .catch() than the 2nd argument to .then() so that's how I've shown it here



                      firstRequest().then(secondRequest).then(r => {
                      console.log('both requests successful');
                      }).catch(err => {
                      // An error from either request will show here
                      console.log(err);
                      });




                      When you provide a catch block and you don't either return a rejected promise or rethrow the error, then the promise infrastructure thinks you have "handled" the promise so the chain continues as resolved. If you rethrow the error, then the next catch block will fire and any intervening .then() handlers will be skipped.



                      You can make use of that to catch an error locally, do something (like log it) and then rethrow it to keep the promise chain as rejected.



                      firstRequest().catch(e => {
                      console.log('firstRequest fail', e));
                      e.logged = true;
                      throw e;
                      }).then(r => {
                      console.log('firstRequest success', r);
                      return secondRequest();
                      }).then(r => {
                      console.log('secondRequest success', r);
                      }).catch(e => {
                      if (!e.logged) {
                      console.log('secondRequest fail', e));
                      }
                      });


                      Or, a version that marks the error object with a debug message and then rethrows and can then only logs errors in one place:



                      firstRequest().catch(e => {
                      e.debugMsg = 'firstRequest fail';
                      throw e;
                      }).then(r => {
                      console.log('firstRequest success', r);
                      return secondRequest().catch(e => {
                      e.debugMsg = 'secondRequest fail';
                      throw e;
                      });
                      }).then(r => {
                      console.log('secondRequest success', r);
                      }).catch(e => {
                      console.log(e.debugMsg, e);
                      });




                      I've even had situations where a little helper function saved me some code and some visual complexity, particularly if there are a bunch of these in the chain:



                      function markErr(debugMsg) {
                      return function(e) {
                      // mark the error object and rethrow
                      e.debugMsg = debugMsg;
                      throw e;
                      }
                      }

                      firstRequest()
                      .catch(markErr('firstRequest fail'))
                      .then(r => {
                      console.log('firstRequest success', r);
                      return secondRequest().catch(markErr('secondRequest fail'));
                      }).then(r => {
                      console.log('secondRequest success', r);
                      }).catch(e => {
                      console.log(e.debugMsg, e);
                      });


                      Taking each of your questions individually:




                      How to implement described logic according to all promises best practices?




                      Described above. I'd say the simplest and best practice is the very first code block I show. If you need to make sure when you get to the final .catch() that you have a uniquely identifiable error so you know which step caused it, then modify the rejected error in each individual function to be unique so you can tell which it was from the one .catch() block at the end. If you can't modify those functions, then you can wrap them with a wrapper that catches and marks their error or you can do that inline with the markErr() type solution I showed. In most cases, you just need to know there was an error and not the exact step it occurred in so usually that isn't necessary for every step in the chain.




                      Is it possible to avoid throw e in every catch block?




                      That depends. If the error objects are already unique, then you can just use one .catch() at the end. If the error objects are not unique, but you need to know which exact step failed, then you have to either use a .catch() at each step so you can mark the error uniquely or you need to modify each function in the chain to have a unique error.




                      Should I use es6 Promises?




                      Yes. No better way I know of.




                      Or it is better to use some promises library?




                      I'm not aware of any features in a promise library that would make this simpler. This is really just about how you want to report errors and whether each step is defining a unique error or not. A promise library can't really do that for you.




                      Any other advice?




                      Keep learning more about how to mold promises into a solution for each individual problem.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 22 at 16:53

























                      answered Nov 22 at 16:16









                      jfriend00

                      426k51545591




                      426k51545591
























                          up vote
                          1
                          down vote













                          IMO, you can use async/await... Still, with promises but is much cleaner to look at. Here is my sample approach on above logic.



                          function firstRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          function secondRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          async function startProgram() {
                          try {
                          await firstRequest();
                          await secondRequest();
                          } catch(err) {
                          console.log(err);
                          goToEndFn();
                          }
                          }

                          startProgram(); // start the program





                          share|improve this answer























                          • This doesn't really answer questions about how the OP logs and handles each individual error separately. This just throws all the errors into one spot which you can do just fine with a regular promise chain too with one .catch() at the end. I think the OP knows that. That isn't what their question is.
                            – jfriend00
                            Nov 22 at 16:59















                          up vote
                          1
                          down vote













                          IMO, you can use async/await... Still, with promises but is much cleaner to look at. Here is my sample approach on above logic.



                          function firstRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          function secondRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          async function startProgram() {
                          try {
                          await firstRequest();
                          await secondRequest();
                          } catch(err) {
                          console.log(err);
                          goToEndFn();
                          }
                          }

                          startProgram(); // start the program





                          share|improve this answer























                          • This doesn't really answer questions about how the OP logs and handles each individual error separately. This just throws all the errors into one spot which you can do just fine with a regular promise chain too with one .catch() at the end. I think the OP knows that. That isn't what their question is.
                            – jfriend00
                            Nov 22 at 16:59













                          up vote
                          1
                          down vote










                          up vote
                          1
                          down vote









                          IMO, you can use async/await... Still, with promises but is much cleaner to look at. Here is my sample approach on above logic.



                          function firstRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          function secondRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          async function startProgram() {
                          try {
                          await firstRequest();
                          await secondRequest();
                          } catch(err) {
                          console.log(err);
                          goToEndFn();
                          }
                          }

                          startProgram(); // start the program





                          share|improve this answer














                          IMO, you can use async/await... Still, with promises but is much cleaner to look at. Here is my sample approach on above logic.



                          function firstRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          function secondRequest() {
                          return new Promise((resolve, reject) => {
                          // add async function here
                          // and resolve("done")/reject("err")
                          });
                          }

                          async function startProgram() {
                          try {
                          await firstRequest();
                          await secondRequest();
                          } catch(err) {
                          console.log(err);
                          goToEndFn();
                          }
                          }

                          startProgram(); // start the program






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 22 at 16:29

























                          answered Nov 22 at 16:21









                          carlokid

                          574




                          574












                          • This doesn't really answer questions about how the OP logs and handles each individual error separately. This just throws all the errors into one spot which you can do just fine with a regular promise chain too with one .catch() at the end. I think the OP knows that. That isn't what their question is.
                            – jfriend00
                            Nov 22 at 16:59


















                          • This doesn't really answer questions about how the OP logs and handles each individual error separately. This just throws all the errors into one spot which you can do just fine with a regular promise chain too with one .catch() at the end. I think the OP knows that. That isn't what their question is.
                            – jfriend00
                            Nov 22 at 16:59
















                          This doesn't really answer questions about how the OP logs and handles each individual error separately. This just throws all the errors into one spot which you can do just fine with a regular promise chain too with one .catch() at the end. I think the OP knows that. That isn't what their question is.
                          – jfriend00
                          Nov 22 at 16:59




                          This doesn't really answer questions about how the OP logs and handles each individual error separately. This just throws all the errors into one spot which you can do just fine with a regular promise chain too with one .catch() at the end. I think the OP knows that. That isn't what their question is.
                          – jfriend00
                          Nov 22 at 16:59










                          up vote
                          1
                          down vote













                          https://github.com/xobotyi/await-of



                          $ npm i --save await-of 




                          import of from "await-of";

                          async () => {
                          let [res1, err1] = await of(axios.get('some.uri/to/get11'));
                          let [res2, err2] = await of(axios.get('some.uri/to/get22'));

                          if (err1) {
                          console.log('err1', err1)
                          }
                          if (err2) {
                          console.log('err2', err2)
                          }
                          console.log('res1', res1)
                          console.log('res2', res2)

                          };





                          share|improve this answer

























                            up vote
                            1
                            down vote













                            https://github.com/xobotyi/await-of



                            $ npm i --save await-of 




                            import of from "await-of";

                            async () => {
                            let [res1, err1] = await of(axios.get('some.uri/to/get11'));
                            let [res2, err2] = await of(axios.get('some.uri/to/get22'));

                            if (err1) {
                            console.log('err1', err1)
                            }
                            if (err2) {
                            console.log('err2', err2)
                            }
                            console.log('res1', res1)
                            console.log('res2', res2)

                            };





                            share|improve this answer























                              up vote
                              1
                              down vote










                              up vote
                              1
                              down vote









                              https://github.com/xobotyi/await-of



                              $ npm i --save await-of 




                              import of from "await-of";

                              async () => {
                              let [res1, err1] = await of(axios.get('some.uri/to/get11'));
                              let [res2, err2] = await of(axios.get('some.uri/to/get22'));

                              if (err1) {
                              console.log('err1', err1)
                              }
                              if (err2) {
                              console.log('err2', err2)
                              }
                              console.log('res1', res1)
                              console.log('res2', res2)

                              };





                              share|improve this answer












                              https://github.com/xobotyi/await-of



                              $ npm i --save await-of 




                              import of from "await-of";

                              async () => {
                              let [res1, err1] = await of(axios.get('some.uri/to/get11'));
                              let [res2, err2] = await of(axios.get('some.uri/to/get22'));

                              if (err1) {
                              console.log('err1', err1)
                              }
                              if (err2) {
                              console.log('err2', err2)
                              }
                              console.log('res1', res1)
                              console.log('res2', res2)

                              };






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 22 at 17:20









                              аlex dykyі

                              1,4011024




                              1,4011024






















                                  up vote
                                  0
                                  down vote













                                  Async/await maybe?



                                  async function foo() {
                                  try {
                                  const firstResult = await firstRequest();
                                  const secondResult = await secondRequest();
                                  } catch(e) {
                                  // e = either first or second error
                                  }
                                  }


                                  In this code an error on the first request transfers control to the catch block and the second request won't start




                                  Should I use es6 Promises?




                                  Probably yes, until you're pretty sure your code will be used in obsolete environments. They are already not so new and flashy






                                  share|improve this answer

























                                    up vote
                                    0
                                    down vote













                                    Async/await maybe?



                                    async function foo() {
                                    try {
                                    const firstResult = await firstRequest();
                                    const secondResult = await secondRequest();
                                    } catch(e) {
                                    // e = either first or second error
                                    }
                                    }


                                    In this code an error on the first request transfers control to the catch block and the second request won't start




                                    Should I use es6 Promises?




                                    Probably yes, until you're pretty sure your code will be used in obsolete environments. They are already not so new and flashy






                                    share|improve this answer























                                      up vote
                                      0
                                      down vote










                                      up vote
                                      0
                                      down vote









                                      Async/await maybe?



                                      async function foo() {
                                      try {
                                      const firstResult = await firstRequest();
                                      const secondResult = await secondRequest();
                                      } catch(e) {
                                      // e = either first or second error
                                      }
                                      }


                                      In this code an error on the first request transfers control to the catch block and the second request won't start




                                      Should I use es6 Promises?




                                      Probably yes, until you're pretty sure your code will be used in obsolete environments. They are already not so new and flashy






                                      share|improve this answer












                                      Async/await maybe?



                                      async function foo() {
                                      try {
                                      const firstResult = await firstRequest();
                                      const secondResult = await secondRequest();
                                      } catch(e) {
                                      // e = either first or second error
                                      }
                                      }


                                      In this code an error on the first request transfers control to the catch block and the second request won't start




                                      Should I use es6 Promises?




                                      Probably yes, until you're pretty sure your code will be used in obsolete environments. They are already not so new and flashy







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Nov 22 at 16:11









                                      Anton Pastukhov

                                      1978




                                      1978






















                                          up vote
                                          0
                                          down vote













                                          you do not need handle error for every promise



                                          you need handle error only as common error



                                          do like this:



                                          var ms = 1000;
                                          var isFirstSucceed = false;
                                          var isSecondSucceed = true;

                                          var getUsersId = () => new Promise((res, rej) => {
                                          console.log('request getUsersId');
                                          setTimeout(() => {
                                          if (isFirstSucceed) {
                                          return res([1,2,3,4,5]);
                                          } else {
                                          return rej();
                                          }
                                          }, ms);
                                          });

                                          var getUserById = () => new Promise((res, rej) => {
                                          console.log('request getUserById');
                                          setTimeout(() => {
                                          if (isSecondSucceed) {
                                          return res({name: 'John'});
                                          } else {
                                          return rej(new Error());
                                          }
                                          }, ms);
                                          });

                                          getUsersId()
                                          .then(r => {
                                          console.info('1st request succeed', r);
                                          return getUserById();
                                          })
                                          .then(r => {
                                          console.info('2st request succeed', r);
                                          return;
                                          })
                                          .catch((e) => {
                                          console.error('request failed', e);
                                          throw new Error(e);
                                          })





                                          share|improve this answer





















                                          • Thanks, but you provided different logic. As I described I need do handling of every request fail. In your example all fails logic was putted to last catch block, but I want to split that logic to a few parts.
                                            – WebBrother
                                            Nov 22 at 16:24















                                          up vote
                                          0
                                          down vote













                                          you do not need handle error for every promise



                                          you need handle error only as common error



                                          do like this:



                                          var ms = 1000;
                                          var isFirstSucceed = false;
                                          var isSecondSucceed = true;

                                          var getUsersId = () => new Promise((res, rej) => {
                                          console.log('request getUsersId');
                                          setTimeout(() => {
                                          if (isFirstSucceed) {
                                          return res([1,2,3,4,5]);
                                          } else {
                                          return rej();
                                          }
                                          }, ms);
                                          });

                                          var getUserById = () => new Promise((res, rej) => {
                                          console.log('request getUserById');
                                          setTimeout(() => {
                                          if (isSecondSucceed) {
                                          return res({name: 'John'});
                                          } else {
                                          return rej(new Error());
                                          }
                                          }, ms);
                                          });

                                          getUsersId()
                                          .then(r => {
                                          console.info('1st request succeed', r);
                                          return getUserById();
                                          })
                                          .then(r => {
                                          console.info('2st request succeed', r);
                                          return;
                                          })
                                          .catch((e) => {
                                          console.error('request failed', e);
                                          throw new Error(e);
                                          })





                                          share|improve this answer





















                                          • Thanks, but you provided different logic. As I described I need do handling of every request fail. In your example all fails logic was putted to last catch block, but I want to split that logic to a few parts.
                                            – WebBrother
                                            Nov 22 at 16:24













                                          up vote
                                          0
                                          down vote










                                          up vote
                                          0
                                          down vote









                                          you do not need handle error for every promise



                                          you need handle error only as common error



                                          do like this:



                                          var ms = 1000;
                                          var isFirstSucceed = false;
                                          var isSecondSucceed = true;

                                          var getUsersId = () => new Promise((res, rej) => {
                                          console.log('request getUsersId');
                                          setTimeout(() => {
                                          if (isFirstSucceed) {
                                          return res([1,2,3,4,5]);
                                          } else {
                                          return rej();
                                          }
                                          }, ms);
                                          });

                                          var getUserById = () => new Promise((res, rej) => {
                                          console.log('request getUserById');
                                          setTimeout(() => {
                                          if (isSecondSucceed) {
                                          return res({name: 'John'});
                                          } else {
                                          return rej(new Error());
                                          }
                                          }, ms);
                                          });

                                          getUsersId()
                                          .then(r => {
                                          console.info('1st request succeed', r);
                                          return getUserById();
                                          })
                                          .then(r => {
                                          console.info('2st request succeed', r);
                                          return;
                                          })
                                          .catch((e) => {
                                          console.error('request failed', e);
                                          throw new Error(e);
                                          })





                                          share|improve this answer












                                          you do not need handle error for every promise



                                          you need handle error only as common error



                                          do like this:



                                          var ms = 1000;
                                          var isFirstSucceed = false;
                                          var isSecondSucceed = true;

                                          var getUsersId = () => new Promise((res, rej) => {
                                          console.log('request getUsersId');
                                          setTimeout(() => {
                                          if (isFirstSucceed) {
                                          return res([1,2,3,4,5]);
                                          } else {
                                          return rej();
                                          }
                                          }, ms);
                                          });

                                          var getUserById = () => new Promise((res, rej) => {
                                          console.log('request getUserById');
                                          setTimeout(() => {
                                          if (isSecondSucceed) {
                                          return res({name: 'John'});
                                          } else {
                                          return rej(new Error());
                                          }
                                          }, ms);
                                          });

                                          getUsersId()
                                          .then(r => {
                                          console.info('1st request succeed', r);
                                          return getUserById();
                                          })
                                          .then(r => {
                                          console.info('2st request succeed', r);
                                          return;
                                          })
                                          .catch((e) => {
                                          console.error('request failed', e);
                                          throw new Error(e);
                                          })






                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Nov 22 at 16:18









                                          аlex dykyі

                                          1,4011024




                                          1,4011024












                                          • Thanks, but you provided different logic. As I described I need do handling of every request fail. In your example all fails logic was putted to last catch block, but I want to split that logic to a few parts.
                                            – WebBrother
                                            Nov 22 at 16:24


















                                          • Thanks, but you provided different logic. As I described I need do handling of every request fail. In your example all fails logic was putted to last catch block, but I want to split that logic to a few parts.
                                            – WebBrother
                                            Nov 22 at 16:24
















                                          Thanks, but you provided different logic. As I described I need do handling of every request fail. In your example all fails logic was putted to last catch block, but I want to split that logic to a few parts.
                                          – WebBrother
                                          Nov 22 at 16:24




                                          Thanks, but you provided different logic. As I described I need do handling of every request fail. In your example all fails logic was putted to last catch block, but I want to split that logic to a few parts.
                                          – WebBrother
                                          Nov 22 at 16:24










                                          up vote
                                          0
                                          down vote













                                          You can abuse duck-typing technique to stop promise chain with return { then: function() {} };. I modified your code just right after this line console.error('1st request failed', e);






                                          var ms = 1000;
                                          var isFirstSucceed = false;
                                          var isSecondSucceed = true;

                                          var getUsersId = () => new Promise((res, rej) => {
                                          console.log('request getUsersId');
                                          setTimeout(() => {
                                          if (isFirstSucceed) {
                                          return res([1,2,3,4,5]);
                                          } else {
                                          return rej(new Error());
                                          }
                                          }, ms);
                                          });

                                          var getUserById = () => new Promise((res, rej) => {
                                          console.log('request getUserById');
                                          setTimeout(() => {
                                          if (isSecondSucceed) {
                                          return res({name: 'John'});
                                          } else {
                                          return rej(new Error());
                                          }
                                          }, ms);
                                          });

                                          getUsersId()
                                          .then(r => {
                                          console.info('1st request succeed', r);
                                          return getUserById();
                                          }, e => {
                                          console.error('1st request failed', e);
                                          return { then: function() {} };
                                          })
                                          .then(
                                          r => console.info('2nd request succeed', r),
                                          e => {
                                          console.error('2nd request failed', e);
                                          throw e;
                                          });








                                          share|improve this answer



























                                            up vote
                                            0
                                            down vote













                                            You can abuse duck-typing technique to stop promise chain with return { then: function() {} };. I modified your code just right after this line console.error('1st request failed', e);






                                            var ms = 1000;
                                            var isFirstSucceed = false;
                                            var isSecondSucceed = true;

                                            var getUsersId = () => new Promise((res, rej) => {
                                            console.log('request getUsersId');
                                            setTimeout(() => {
                                            if (isFirstSucceed) {
                                            return res([1,2,3,4,5]);
                                            } else {
                                            return rej(new Error());
                                            }
                                            }, ms);
                                            });

                                            var getUserById = () => new Promise((res, rej) => {
                                            console.log('request getUserById');
                                            setTimeout(() => {
                                            if (isSecondSucceed) {
                                            return res({name: 'John'});
                                            } else {
                                            return rej(new Error());
                                            }
                                            }, ms);
                                            });

                                            getUsersId()
                                            .then(r => {
                                            console.info('1st request succeed', r);
                                            return getUserById();
                                            }, e => {
                                            console.error('1st request failed', e);
                                            return { then: function() {} };
                                            })
                                            .then(
                                            r => console.info('2nd request succeed', r),
                                            e => {
                                            console.error('2nd request failed', e);
                                            throw e;
                                            });








                                            share|improve this answer

























                                              up vote
                                              0
                                              down vote










                                              up vote
                                              0
                                              down vote









                                              You can abuse duck-typing technique to stop promise chain with return { then: function() {} };. I modified your code just right after this line console.error('1st request failed', e);






                                              var ms = 1000;
                                              var isFirstSucceed = false;
                                              var isSecondSucceed = true;

                                              var getUsersId = () => new Promise((res, rej) => {
                                              console.log('request getUsersId');
                                              setTimeout(() => {
                                              if (isFirstSucceed) {
                                              return res([1,2,3,4,5]);
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              var getUserById = () => new Promise((res, rej) => {
                                              console.log('request getUserById');
                                              setTimeout(() => {
                                              if (isSecondSucceed) {
                                              return res({name: 'John'});
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              getUsersId()
                                              .then(r => {
                                              console.info('1st request succeed', r);
                                              return getUserById();
                                              }, e => {
                                              console.error('1st request failed', e);
                                              return { then: function() {} };
                                              })
                                              .then(
                                              r => console.info('2nd request succeed', r),
                                              e => {
                                              console.error('2nd request failed', e);
                                              throw e;
                                              });








                                              share|improve this answer














                                              You can abuse duck-typing technique to stop promise chain with return { then: function() {} };. I modified your code just right after this line console.error('1st request failed', e);






                                              var ms = 1000;
                                              var isFirstSucceed = false;
                                              var isSecondSucceed = true;

                                              var getUsersId = () => new Promise((res, rej) => {
                                              console.log('request getUsersId');
                                              setTimeout(() => {
                                              if (isFirstSucceed) {
                                              return res([1,2,3,4,5]);
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              var getUserById = () => new Promise((res, rej) => {
                                              console.log('request getUserById');
                                              setTimeout(() => {
                                              if (isSecondSucceed) {
                                              return res({name: 'John'});
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              getUsersId()
                                              .then(r => {
                                              console.info('1st request succeed', r);
                                              return getUserById();
                                              }, e => {
                                              console.error('1st request failed', e);
                                              return { then: function() {} };
                                              })
                                              .then(
                                              r => console.info('2nd request succeed', r),
                                              e => {
                                              console.error('2nd request failed', e);
                                              throw e;
                                              });








                                              var ms = 1000;
                                              var isFirstSucceed = false;
                                              var isSecondSucceed = true;

                                              var getUsersId = () => new Promise((res, rej) => {
                                              console.log('request getUsersId');
                                              setTimeout(() => {
                                              if (isFirstSucceed) {
                                              return res([1,2,3,4,5]);
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              var getUserById = () => new Promise((res, rej) => {
                                              console.log('request getUserById');
                                              setTimeout(() => {
                                              if (isSecondSucceed) {
                                              return res({name: 'John'});
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              getUsersId()
                                              .then(r => {
                                              console.info('1st request succeed', r);
                                              return getUserById();
                                              }, e => {
                                              console.error('1st request failed', e);
                                              return { then: function() {} };
                                              })
                                              .then(
                                              r => console.info('2nd request succeed', r),
                                              e => {
                                              console.error('2nd request failed', e);
                                              throw e;
                                              });





                                              var ms = 1000;
                                              var isFirstSucceed = false;
                                              var isSecondSucceed = true;

                                              var getUsersId = () => new Promise((res, rej) => {
                                              console.log('request getUsersId');
                                              setTimeout(() => {
                                              if (isFirstSucceed) {
                                              return res([1,2,3,4,5]);
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              var getUserById = () => new Promise((res, rej) => {
                                              console.log('request getUserById');
                                              setTimeout(() => {
                                              if (isSecondSucceed) {
                                              return res({name: 'John'});
                                              } else {
                                              return rej(new Error());
                                              }
                                              }, ms);
                                              });

                                              getUsersId()
                                              .then(r => {
                                              console.info('1st request succeed', r);
                                              return getUserById();
                                              }, e => {
                                              console.error('1st request failed', e);
                                              return { then: function() {} };
                                              })
                                              .then(
                                              r => console.info('2nd request succeed', r),
                                              e => {
                                              console.error('2nd request failed', e);
                                              throw e;
                                              });






                                              share|improve this answer














                                              share|improve this answer



                                              share|improve this answer








                                              edited Nov 22 at 21:06

























                                              answered Nov 22 at 17:02









                                              meteorzero

                                              436414




                                              436414






























                                                  draft saved

                                                  draft discarded




















































                                                  Thanks for contributing an answer to Stack Overflow!


                                                  • Please be sure to answer the question. Provide details and share your research!

                                                  But avoid



                                                  • Asking for help, clarification, or responding to other answers.

                                                  • Making statements based on opinion; back them up with references or personal experience.


                                                  To learn more, see our tips on writing great answers.





                                                  Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                  Please pay close attention to the following guidance:


                                                  • Please be sure to answer the question. Provide details and share your research!

                                                  But avoid



                                                  • Asking for help, clarification, or responding to other answers.

                                                  • Making statements based on opinion; back them up with references or personal experience.


                                                  To learn more, see our tips on writing great answers.




                                                  draft saved


                                                  draft discarded














                                                  StackExchange.ready(
                                                  function () {
                                                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434539%2fimplementation-of-simple-request-chain-logic-with-promises%23new-answer', 'question_page');
                                                  }
                                                  );

                                                  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







                                                  Popular posts from this blog

                                                  Contact image not getting when fetch all contact list from iPhone by CNContact

                                                  count number of partitions of a set with n elements into k subsets

                                                  A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks