1

This might be little opinion based, but an important question.

Should you use promises only for async operations? If you have an api, then very likely, the full stack of functions in there should use promises. So then if I make some business logic functions, they also should return a promise. I wonder if this is good, that you make everything return a promise. I mean, I'm calling functions inside a while loop, where each of them returns a promise (the functions are chained). Is it slower to use promises inside a function? Is it good idea in a stack to combine promises and regular return values? I really need to learn this, so please don't close

Ville Miekk-oja
  • 18,749
  • 32
  • 70
  • 106
  • 6
    If your function is asynchronous, it needs to return a promise. If it doesn't do anything asynchronous, there's no good reason for it to return a promise, and you should avoid it. – Bergi Sep 07 '16 at 11:58
  • Yes, but you replied in another questions comment that: "Yes. "sometimes synchronous" is a very bad idea, so we always return a promise." When I said: "Okay, so it is okay to return a promise from synchronous operations." Look: http://stackoverflow.com/questions/38866725/nodejs-using-promises-for-api-calls – Ville Miekk-oja Sep 07 '16 at 12:02
  • It's more "It is okay to return a promise from a synchronous operations when it takes place in a context where you're unsure the operation will be synchronous" – Denys Séguret Sep 07 '16 at 12:05
  • 2
    There's a difference between sometimes synchronous and always synchronous. eg "Have I made this horribly slow web request and cached the result yet?" No->make the request and return a promise. Yes->return the cached response. Now you're returning two different things from the same function. This is where you would always return a promise from a "sometimes synchronous" function, so the calling code doesn't need to care whether it's happening asynchronously or not. – James Thorpe Sep 07 '16 at 12:05
  • 2
    Simple question: would you make `String.substr` asynchronous? No, hopefully not, because it makes no sense. So you will *always* have a mix of synchronous and asynchronous code, and which to use for any particular function depends on what that function is supposed to do. – deceze Sep 07 '16 at 12:06

1 Answers1

3

If your function is (sometimes) asynchronous, it needs to return a promise.
If your function never does anything asynchronous, there's no good reason for it to return a promise, and you should avoid it. Keep it simple and synchronous.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • You might also want to have a look at [Synchronous code in then handler of Promise](http://stackoverflow.com/q/36605186/1048572) – Bergi Sep 07 '16 at 12:33
  • Can I then chain async and sync functions together? For example: I would want to first make an api call, then chain that to validateResponse function, and if there is an error in any of those, then I want to catch it. Can I do it? It would be very simple with promises: sendQuery().then(validateResponse).then(transformResponse).catch(err...). The validation and transform functions are synchronous, but it would need to return a promise for the chain to continue, and for the catch get errors from all of them? Also, if this whole chain is inside one main api function, should that return a promise? – Ville Miekk-oja Sep 07 '16 at 12:40
  • @VilleMiekk-oja: I kinda knew you were going to ask that, so I posted the link above :-) Yes, Yes, Yes,and Yes. – Bergi Sep 07 '16 at 12:47
  • I read the link, but didn't understand fully. Because the validateResponse and transformResponse are synchronous, they should not return a promise. But how can I then relay their return value to the next then function? Since then is related to the promises? Should it be like this: sendQuery().then(function(results) {var validatedRes = validateResponse(); return transformResponse(validatedRes)}).catch(err..)... – Ville Miekk-oja Sep 07 '16 at 13:02
  • 2
    @VilleMiekk-oja `then` doesn't care whether its callbacks return a promise or plain value, it will be `Promise.resolve`'d anyway. Your `.then(validateResponse).then(transformResponse)` works. Upon re-reading your comment, my third "Yes" should probably have been a "No", you don't "*need to return a promise* [from the callback] *for the chain to continue*". – Bergi Sep 07 '16 at 13:38
  • But what if you don't want the result of the sync functions return value to be resolved? I mean, what if the validateResponse fails (response not valid)? What I would then maybe want is, that instead of resolving, it would be rejected, and then my last catch function would catch the error. – Ville Miekk-oja Sep 07 '16 at 13:48
  • 1
    @VilleMiekk-oja It should `throw` an exception like any synchronous function. `then` will catch these and turn them into rejections, so that it works exactly like you expect. – Bergi Sep 07 '16 at 14:00