Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
scroll top