Search code examples
javascriptes6-promise

returning to caller from deep nested dependent promise in javascript


I have common scenario but I don't find solution anywhere without a callback method. Here is what I have: from a service method, calling a helper method in another file, from helper calling a worker method which performs a sequence of async operations. they are dependent one another.

let myParentPromise = MyService.serviceFunc(in1, in2);
myParentPromise.then(res => console.log(res));
myParentPromise.catch(exc => console.log(exc));

service layer:

serviceFunc: (in1, in2) => {
  return new Promise((resolve, reject) => {
     //some processing
     let helperPromise = MyHelper.helperFunc(in1,in2);
      helperPromise.then(res => 
      //processing
      {resolve(res)});
      helperPromise.catch(exc => {reject(exc)})
  })

Helper Layer:

helperFunc: (in1, in2) => {
return new Promise((resolve, reject) =>{
    resolve(async1);
  }).then(res1 =>{
    return async2;
  }).then(res2 => {
  return res2;

  })
}

I want to pass res2 to my service layer then to myParentPromise.

how to do that? Is it possible to do that without using callbacks? I like to purely use promises to do this job.

any help would be appreciated.


Solution

  • I suggest you take a look at the docs here.

    If you return the promises you can chain them. You're already returning res2, the only thing left in order to be able to get that value in myParentPromise is the following:

    const finalResult = serviceFunc(in1, in2)
      .then(res => res)
      .catch(exc => exc);
    
    const serviceFunc = (in1, in2) =>
      helperFunc(in1, in2)
        .then(res => res)
        .catch(exc => exc);
    
    const helperFunc = (in1, in2) => async1.then(res1 => async2).then(res2 => res2);
    

    Finally, I would suggest you read about async/await which is, in my opinion, an improvement to the codebase.

    [Edit] Updated the code and add examples of reducing nesting.

    So the problem with nesting is that you make the asynchronous code obscure, may catch error incorrectly and even worse, may create a new chain of promises that races against the first one, this is explained very well here.

    So, how to avoid all of this: return the promises as you can see in the example above. This other post is a good explanation of why it's an antipattern and how to fix it :).

    Now, how to reduce nesting? There are two ways that I can think of:

    • Just chain promises at the top level, which is not always the most simple, elegant, and better code, but plausible. You can see a good example here.
    • Use async/await.

    Just keep always in mind that you're working with async code and as a rule of thumb, always return the promises. Happy coding!