4

Promises is a fairly new pattern for me, so I'm still building my intuition for them.

I recently came across a case where some code in an adapter-like bit of code was once synchronous, and then became asynchronous, so promises were introduced. Consider:

function runCalculation() {
  var params = this.getParams();
  this.callLibraryCalculation(params);
}

Here, getParams collects values from various places and puts them in one object that can be used by callLibraryCalculation, which wraps, as you would expect, a call from an external source. All this is obviously simplified for the purpose of the question.

So this all worked, until a new use case required getParams to retrieve some of it's values from an external API, introducing asynchronous behavior. So that function was altered to handle async, using and returning a promise. Which means consuming it has changed.

function runCalculation() {
  return this.getParams().then(function(params) {
    this.callLibraryCalculation(params);
  });
}

I choose to return the promise here because the functions that call runCalculation have dependent logic that needs to be .then()-ed. but my question is about the callers of runCalculation. They are now producing their own promises as a result of consuming the one returned here. I can currently let most of those promises escape into the ether, because the callers represent the end of execution. But I notice that in the case where it is not end of execution, this passing of promises begins to invade a great deal of code, bubbling from caller to caller.

My inclination is to always return a promise from a function that must use one to order it's logic.

Is that inclination good intuition? Should I be worried that Promises, once introduced, start to take over my code?

Or to ask in a more answerable question: Are there considerations I may have missed that speak for or against such a practice?

5

My inclination is to always return a promise from a function that must use one to order it's logic.

If you have a function with an async operation and you're using promises and there's ever ANY reason for the caller of the function to want to know when the async operation is done or what its final value is, then by all means just return the promise you already have internally.

This gives the caller more flexibility. If the caller chooses to not use the returned promise, that's no problem. At least it's there if the caller wants to use it.

Should I be worried that Promises, once introduced, start to take over my code?

I'm not sure what you mean by "take over your code". If you want to give a caller access to async completion, then return a promise. If you don't want to give a caller access to the async completion, then don't return a promise. It's no more complex than that.

Any async operation in a function makes the containing function async. It's contagious in that regard. And, promises are the best way to deliver async results and coordinate multiple async operations. So, all code that uses async operations should use promises. This isn't "taking over your code" - it's the intelligent way to design your async code. If it seems unnatural to you now, then you just need more experience and practice doing it and it will start to become natural and easy. At that point, it won't feel like anything took over your code, but rather that you're using the right tools for the job.

  • 2
    @Basilevs - well, that's just the way it is with async. Any operation that uses an async API immediately changes the entire operation to be async. There's nothing you can do about that - that's just the way it is. – jfriend00 Jan 9 '16 at 5:01
  • @Basilevs - I added another paragraph to the end of my answer. – jfriend00 Jan 9 '16 at 5:10
  • 4
    +1 Pretty much exactly what I wanted to write. The only thing I'd add is that this is just as true if you use callbacks instead of promises, or have functions that "convert" a callback to a promise or vice versa, just to hammer home the point that async-ness is inherently "infectious", and it's got nothing to do with promises specifically. – Ixrec Jan 9 '16 at 12:34
  • I believe it really was the "infectiousness" of asynchrony that worried, more than Promises. I just felt I might be missing something in the proper patterns of using Promises that might mitigate that in some way. I'm now confident that that is not something I was just missing. Thanks all for helping me sort it out. – TwainJ Jan 12 '16 at 1:23
  • Async in .net is very good example, because of strong types you are forced to return Task(Promise in .net world). So one method which uses asynchronous approach and all callers should be changed to return it too. – Fabio Feb 15 '18 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.