should i use `return` in Promise?

前端 未结 3 754
忘了有多久
忘了有多久 2020-12-02 18:48
function saveToTheDb(value) {  
  return new Promise(function(resolve, reject) {
    db.values.insert(value, function(err, user) { // remember error first ;)
      i         


        
相关标签:
3条回答
  • 2020-12-02 19:34

    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
    });
    
    0 讨论(0)
  • 2020-12-02 19:37

    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

    0 讨论(0)
  • 2020-12-02 19:42

    As @JaromandaX said in this case the return statement does not make any diference. From the docs:

    In all cases where a promise is resolved (i.e. either fulfilled or rejected), the resolution is permanent and cannot be reset. Attempting to call resolve, reject, or notify if promise is already resolved will be a no-op.

    0 讨论(0)
提交回复
热议问题