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

时间:2016-01-08 03:06:38

标签: 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);
    })
  }
}

以下是我从here看到的代码。 我对return关键字感到困惑。

对于resolve(user);,我需要return吗?

对于reject(user);,我需要return吗?

3 个答案:

答案 0 :(得分:37)

无需在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);
      }
    });
  }
}

在这种情况下,您使用了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);
    });
  }
}

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

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

所以,这在技术上也会起作用,但不被认为是最佳实践,因为它执行不必要的代码并且没有结构清晰:

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

仅供参考,你在这里做的事情被称为" promisifying"这使得一个常规的异步函数与回调函数一起使用,该函数返回一个promise。有一些图书馆和功能将会“宣传”#34;一个函数调用中的函数或整个函数对象(例如整个API),因此您不必手动执行此操作。例如,我经常使用Bluebird,它提供Promise.promisify()用于宣传单个函数或Promise.promisifyAll(),它将宣传对象或原型上的所有方法。这非常有用。例如,您可以使用以下内容获得整个fs模块的promisified版本:

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

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

fs.readFileAsync("file.txt").then(function(data) {
    // do something with file.txt data here
});

答案 1 :(得分:1)

通常,在NodeJS中,您不应该非常使用promise构造函数。

承诺构造函数用于converting APIs that don't return promises to promises。您应该考虑使用提供promisification的库(即使您全面使用本机承诺),因为它提供了一个安全的替代方案,它没有错误处理逻辑的细微错误。

自动宣传也相当快。

那就是说,你的问题的答案是“是”。

这样做非常安全,promise构造函数没有什么特别之处 - 它们只是简单的JavaScript。 Domenic讨论了promise构造函数in his blog的设计。

早期返回是完全安全的(就像任何其他函数一样) - 它在常规异步函数中非常常见。

(另外,在您的示例代码中,您应该只使用Promise.resolve,但我认为 只是简单,因为它是一个示例。)

从重复

复制此答案

答案 2 :(得分:-1)

正如@JaromandaX所说,在这种情况下,return语句没有任何不同之处。 来自docs

  

在承诺得到解决(即已履行或拒绝)的所有情况下,解决方案都是永久性的,无法重置。如果承诺已经解决,尝试呼叫解决,拒绝或通知将是无操作。