【问题标题】:Promisification by using resolve or reject or with Promisify (bluebird)通过使用 resolve 或 reject 或 Promisify (bluebird) 进行承诺
【发布时间】:2015-02-05 06:03:22
【问题描述】:

您好,我有一个方法,我使用 bluebird 提供的 Promise 类根据第三方函数的结果来解决或拒绝。我担心的是第三方函数是同步的,因此可能会引发错误。以下是我的代码:

Authenticator.prototype.createJWTResponse = function(user, secret) {
  if (user && user.ID) {
    var expires = moment().add(7, 'days').valueOf();
    //encode is third party and synchronous that can throw error
    var token = jwt.encode({
      iss: user.ID,
      exp: expires
    }, secret);

    //throw new Error("thrown by a promise method");

    return Promise.resolve({
      token: token,
      expires: expires,
      user: {}
    });

  } else {
    return Promise.reject(new Error('Authenticator:createJWTResponse: user object missing or doesnt have ID'));
  }
};

一种选择是我不在方法中使用拒绝和响应,而是将其设为正常的回调方法,然后由 Promise.promisify 承诺。但是我的问题是;如果有办法使用resolve和reject并创建一个promise,以防第三方方法抛出异常。 我的另一个问题是;蓝鸟文档中没有说明;如果有人在方法中使用resolve和reject;可以承诺这种方法吗? 我试图承诺上述方法,但由于某种原因它无法返回并且没有抛出错误;这让我怀疑,如果一个人在一个方法中使用了 resolve,reject,那么这样的方法就不能被承诺。

有人可以为我澄清一下吗?提前致谢。

(更新)

如果我将方法包装在 Promise.method 中; bluebird 抛出一个非常明显的错误如下:

可能未处理的错误:否则承诺返回方法中的同步错误

从该方法内部返回 Promise.try 也会引发与 Promise.method 相同的错误。

将方法中的代码包装在 try catch 中并在错误时拒绝也会抛出:

可能未处理的错误:

(解决方案)

按照本杰明的建议;从方法中删除所有解析和拒绝调用并将其包装在 Promise.method 中会产生预期的结果。最终代码如下:

Authenticator.prototype.createJWTResponse = Promise.method(function(user, secret) {
  if (user && user.ID) {
    var expires = moment().add(7, 'days').valueOf();
    var token = jwt.encode({
      iss: user.ID,
      exp: expires
    }, secret);

    //Note: This is caught by the catch block on this method
    //throw new Error('sync error thrown');

    return {
      token: token,
      expires: expires,
      user: {}
    }
  } else {
    throw new Error('Authenticator:createJWTResponse: user object missing or doesnt have id');
  }
});

在这种情况下,甚至不需要回调。

【问题讨论】:

  • 为什么不把第三方方法放在 try/catch 块中,并在出错时返回一个被拒绝的承诺
  • @johndoe90 这似乎是在不使用 promisify 的情况下让代码正常工作的最合乎逻辑的方式。

标签: javascript node.js promise bluebird


【解决方案1】:

首先 .promisify 已经将抛出转换为拒绝。

至于普通的promisification——promise构造函数是安全的,你可以使用Promise.method,它是安全的。

同步抛出转换为拒绝的原因是为了创建一致的 API,因此您不必一直 .catch 和 catch。

【讨论】:

  • .promisify 只能在需要回调的函数上正常工作,这就是它在这里不起作用的原因。
  • 如果一个函数已经返回了一个promise,那么就不需要promisify它,另一方面,如果一个函数是同步的,那么就不需要promisify它
  • Aaron 我最初有这个方法接受一个工作正常的回调。然而,我的逻辑是尽量保持一致并首先使用承诺,这样我就不必承诺每一种方法。
  • @Nosh 如果您只想将返回值/抛出转换为返回的解析/拒绝,只需使用Promise.method
猜你喜欢
  • 2015-05-11
  • 2016-07-27
  • 1970-01-01
  • 2019-09-15
  • 2018-02-01
  • 1970-01-01
  • 2014-07-15
  • 1970-01-01
  • 2018-08-07
相关资源
最近更新 更多