1

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.

praveen seela
  • 538
  • 11
  • 24
  • either I don't understand what you want to do or you are already doing that as in `MyHelper.helperFunc` returns promise to `helperPromise ` and this one is returning it myParentPromise. You could write it a little bit simpler but that wouldn't make much difference – Xesenix Jun 13 '20 at 02:54
  • `return res2` is not returning to `serviceFunc`, that's the problem. I tried even return` new Promise` in place of `return res2` but not working. – praveen seela Jun 13 '20 at 04:53
  • what is your problem https://stackblitz.com/edit/js-9yjryl it returns res2 which is the value you had in async2 – Xesenix Jun 13 '20 at 08:29
  • What are `async1` and `async2`? – Bergi Jun 13 '20 at 15:50
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! And also never use `p.then(…); p.catch(…)` which forks the chain and causes unhandled rejections in the promise returned by `p.then(…)`. – Bergi Jun 13 '20 at 15:50
  • @Bergi I mention that in my answer. – alexfertel Jun 13 '20 at 20:07

1 Answers1

1

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!

alexfertel
  • 925
  • 1
  • 9
  • 22