Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

should i use `return` in Promise?

function saveToTheDb(value) {     return new Promise(function(resolve, reject) {     db.values.insert(value, function(err, user) { // remember error first ;)       if (err) {         return reject(err); // don't forget to return here       }       resolve(user);     })   } } 

Here is the code which i see from here. i am confused about return keyword.

For resolve(user);, do i need return?

For reject(user);, do i need return?

like image 799
BlackMamba Avatar asked Jan 08 '16 03:01

BlackMamba


People also ask

Can I return value from promise?

Promise resolve() method:If the value is a promise then promise is returned. If the value has a “then” attached to the promise, then the returned promise will follow that “then” to till the final state. The promise fulfilled with its value will be returned.

Do I need to return reject promise?

Technically it is not needed here1 - because a Promise can be resolved or rejected, exclusively and only once. The first Promise outcome wins and every subsequent result is ignored.

Should async function return promise?

The word “async” before a function means one simple thing: a function always returns a promise. Other values are wrapped in a resolved promise automatically. So, async ensures that the function returns a promise, and wraps non-promises in it.

Should we use return await?

However, if you want to catch the rejected promise you're returning from an asynchronous function, then you should definitely use return await promise expression and add deliberately the await . catch(error) {...} statement catches only awaited rejected promises in try {...} statement.


2 Answers

There is no need to use a return statement inside a new Promise() callback. The Promise constructor is not expecting any sort of return value from the callback.

So, the reason to use a return statement inside that callback is only to control the flow of execution in that function. If you want execution inside your callback to finish and not execute any more code within that callback, you can issue a return; at that point.

For example, you could have written your code like this with no return statement:

function saveToTheDb(value) {     return new Promise(function(resolve, reject) {     db.values.insert(value, function(err, user) {        if (err) {         reject(err);       } else {         resolve(user);       }     });   } } 

In this case, you used the if/else clause to make sure the flow of control in your function takes the correct path and no return was needed or used.


A common shortcut when promisifying async functions like this is:

function saveToTheDb(value) {     return new Promise(function(resolve, reject) {     db.values.insert(value, function(err, user) {        if (err) return reject(err);       resolve(user);     });   } } 

This is not functionally different than the previous code block, but it is less typing and more compact. The return statement in front of reject(err); is only for flow of control reasons to prevent from executing the resolve(user); statement in case of error since the desired flow of control is to call reject(err) and then not execute anything else in the callback.


In fact, the return statement in this last block is not actually even needed in this specific case because executing a resolve() after a reject() will not do anything since promises are latched to whichever happens first resolve or reject. But, it is generally considered poor practice to execute unnecessary code so many would argue that it is better to use flow of control structures such as if/else or return to only execute the code that is needed.

So, this would technically work too, but is not considered a best practice because it executes unnecessary code and isn't as clearly structured:

function saveToTheDb(value) {     return new Promise(function(resolve, reject) {     db.values.insert(value, function(err, user) {       if (err) reject(err);       resolve(user);     });   } } 

FYI, what you are doing here is called "promisifying" which makes a regular async function that works with a callback into a function that returns a promise. There are libraries and functions that will "promisify" a function or a whole object of functions (e.g. a whole API) for you in one function call so you don't have to do this manually. For example, I regularly use Bluebird which offers Promise.promisify() for promisifying a single function or Promise.promisifyAll() which will promisify all the methods on an object or prototype. This is very useful. For example, you could get promisified versions of the entire fs module with just this:

var Promise = require('bluebird'); var fs = Promise.promisifyAll(require('fs')); 

Then, you can use methods that return a promise such as:

fs.readFileAsync("file.txt").then(function(data) {     // do something with file.txt data here }); 
like image 62
jfriend00 Avatar answered Sep 24 '22 18:09

jfriend00


Generally, in NodeJS, you shouldn't use the promise constructor very much.

The promise constructor is for converting APIs that don't return promises to promises. You should consider using a library that provides promisification (even if you use native promises all-around) since it provides a safe alternative that does not have subtle errors with error-handling logic.

Automatic promisification is also considerably faster.

That said, the answer to your question is "Yes".

It is perfectly safe to do so, there is nothing special about promise constructors - they are just plain JavaScript. Domenic discusses the design of the promise constructor in his blog.

It is perfectly safe (just like any other function) to return early - it is actually quite common in regular asynchronous functions.

(Also, in your example code you should just use Promise.resolve, but I assume it was that simple only because it is an example).

Copied this answer from duplicate

like image 44
Benjamin Gruenbaum Avatar answered Sep 25 '22 18:09

Benjamin Gruenbaum