我应该在Promise中使用`return`吗?

Bla*_*mba 22 node.js 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);
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我从这里看到的代码.我对return关键字感到困惑.

因为resolve(user);,我需要return吗?

因为reject(user);,我需要return吗?

jfr*_*d00 40

无需在new Promise()回调中使用return语句.Promise构造函数不期望来自回调的任何类型的返回值.

因此,return在该回调中使用语句的原因只是为了控制该函数中的执行流程. 如果您希望在回调中执行完成而不在该回调中执行任何更多代码,则可以return;在此时发出.

例如,您可以编写这样的代码而不使用return语句:

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

在这种情况下,您使用if/else子句来确保函数中的控制流采用正确的路径,而不return需要或使用.


宣传异步函数时常见的快捷方式是:

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

这与前面的代码块在功能上没有区别,但它的输入更少,更紧凑.return前面的语句reject(err);仅用于控制流的原因,以防止resolve(user);在出现错误时执行语句,因为所需的控制流是要调用reject(err),然后不在回调中执行任何其他操作.


实际上,return在这个特定情况下实际上甚至不需要最后一个块中的语句,因为执行a resolve()之后reject()将不会执行任何操作,因为promise会被锁定到先发生的任何一个解析或拒绝.但是,执行不必要的代码通常被认为是不好的做法,因此许多人认为最好使用控制结构流,例如if/elsereturn仅执行所需的代码.

因此,这在技术上也可以工作,但不被认为是最佳实践,因为它执行不必要的代码并且结构不清晰:

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

仅供参考,你在这里所做的是"promisifying",它使一个常规的异步函数与回调函数一起工作,返回一个promise.有一些库和函数可以在一个函数调用中为您"实现"函数或整个函数对象(例如整个API),因此您不必手动执行此操作.例如,我经常使用Bluebird,它可以Promise.promisify()宣传单一功能,或者Promise.promisifyAll()宣传对象或原型上的所有方法.这非常有用.例如,您可以使用以下方法获得整个fs模块的promisified版本:

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用返回承诺的方法,例如:

fs.readFileAsync("file.txt").then(function(data) {
    // do something with file.txt data here
});
Run Code Online (Sandbox Code Playgroud)