【问题标题】:Resolving a Promise without calling the 'then'在不调用“then”的情况下解决 Promise
【发布时间】:2016-01-26 07:13:25
【问题描述】:

我有这段代码,它是我正在为一个名为 Poolio 的 NPM 模块编写的小 API 的一部分。对于那些支持错误优先回调和承诺的人来说,我的问题似乎是一个常见问题——我们如何在保持一致的 API 和一致的 API 返回值的同时支持这两者?例如,如果我有条件地从我的 API 返回一个 Promise,这取决于我的 lib 的使用者是否提供回调,这在我看来有点尴尬。

lib 的使用者可以提供回调或使用 Promise then 函数,但不能同时提供。

这是我的库导出的一个函数,我想承诺:

Pool.prototype.any = function (msg, cb) {

    var workId = this.counter++;
    var self = this;

    return new Promise(function (resolve, reject) {

        if (typeof cb === 'function') {
            self.resolutions.push({
                workId: workId,
                cb: cb
            });
        }
        else {
            self.resolutions.push({
                workId: workId,
                resolve: resolve,
                reject: reject
            });
        }

        if (this.available.length > 0) {
            var cp = this.available.shift();
            cp.workId = workId;
            cp.send(msg);
        }
        else {
            self.msgQueue.push({
                workId: workId,
                msg: msg
            });
        }
    });

};

我的问题是 - 如果用户在原始函数参数中提供回调函数,我如何在不调用“then”的情况下解决承诺? 抱歉很难解释,但希望你能理解。

还有一个有趣的问题: Do never resolved promises cause memory leak?

【问题讨论】:

  • 解决promise与then无关...一个promise可以独立于任何then被调用的回调来解决
  • if 在 promise 上有一个 then 被调用,那么从 promise 内部调用 resolve 应该调用所有附加的 then,对吧?换句话说,如果没有thens,那么调用resolve应该没有效果,但是如果有thens,那么应该调用那些thens。我的问题是如何避免给他们打电话。
  • 是的,解决后的任何“附加”都将被称为“立即”(在引号中,因为它不是那么明确)
  • My question is how to avoid calling them - 啊哈,我明白了!对不起,完全错过了你的问题的重点
  • 如果用户提供了回调函数,那么你就不会将解析/拒绝函数“推送”到解析中,所以无论如何你永远无法调用解析

标签: javascript node.js es6-promise


【解决方案1】:

实际上非常简单。只有你可能错过了它,因为它隐藏在一堆乱七八糟的代码中。

基本上你这样做:

var promise = new Promise(function (resolve, reject) { /*....*/});

if (typeof cb === 'function') {
    promise.then(cb);
} else {
    return promise;
}

【讨论】:

【解决方案2】:

实际上,这是 API 做的很常见的事情 (mongodb-driver example)。基本上,编写一个接受回调的私有函数,编写一个公共函数检查 cb 并在必要时编写它。使用 github 中的代码(_any 可能需要重构,例如,您不需要检查 cb 是否是一个函数,也许还有其他东西):

 // private function
var _any = function(msg, cb) {
  if (this.kill) {
    console.log('warning: pool.any called on pool of dead/dying workers');
    return;
  }

  debug('current available pool size for pool_id ' + this.pool_id + ' is: ' + this.available.length);
  var workId = this.counter++;

  if (typeof cb === 'function') {
    this.resolutions.push({
      workId: workId,
      cb: cb
    });
  } else {
    workId = -1;
  }

  if (this.available.length > 0) {
    var cp = this.available.shift();
    cp.workId = workId;
    cp.send(msg);
  } else {
    this.msgQueue.push({
      workId: workId,
      msg: msg
    });
  }
};

 // public exposed function
Pool.prototype.any = function(msg, cb) {
  if (typeof cb === 'function') {
    // cb is provided, no action is required here
    return _any(msg, cb);
  } 

  // no cb, wrap the call inside a Promise and provide a cb
  return new Promise(function(resolve, reject) {
    _any(msg, function(err, data) {
      if (err) reject(err);
      else resolve(data);
    });
  });
}

【讨论】:

  • 如果没有回调,您将不会返回承诺,因此调用 pool.any().then() 将不起作用。
  • @slebetman return new Promise() 似乎正在向我回报一个承诺。 OP 可以检查msg 是否存在于_any() 中,我正在概述不编写完整的错误检查代码的想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
  • 2019-02-27
  • 2017-09-24
  • 2021-09-14
相关资源
最近更新 更多