【问题标题】:Why my promise cant resolve?为什么我的承诺无法解决?
【发布时间】:2017-09-13 19:02:38
【问题描述】:

我有两个承诺。一个没有解决,我不知道为什么。

processTradeOffer:尝试处理名为'offer'的对象的承诺链。 identifyOffer 返回一个可能是 "valida" 的变量 | “可接受” | “可否认”。如果是“有效”,我们需要从报价中识别项目。所以我们需要另一个异步函数 identifyItems(offer) 将返回 var 'offerState' "denegable" | “可接受”,然后我们可以拒绝或接受报价。

我知道声明中没有问题(offerState == 'valida')。 代码:

const processTradeOffer = function(offer) {
    return new Promise(function(resolve, reject) {
        identyOffer(offer)
            .then(function(offerState) {
                return finishTradeOffer(offer, offerState);
            }).then(function() {
                console.log('aqui');
                return resolve();
            })
    })
}
const finishTradeOffer = function(offer, offerState) {

    return new Promise(function(resolve, reject) {
        if (offerState == 'aceptable') {
            acceptTradeOffer(offer).then(function() {
                return resolve();
            })
        } else if (offerState == 'denegable') {
            declineTradeOffer(offer).then(function() {
                console.log('here');
                return resolve();
            })
        } else if (offerState == 'valida') {
            identifyItems(offer).then(function(offerState) {
                finishTradeOffer(offer, offerState);
            })
        }
    })
}

Console.log('here') 成功触发,Console.log('aqui') 不成功。

【问题讨论】:

  • 你根本不应该使用new Promise()
  • 如果offerstate == 'valida' 会发生什么?顺便说一句,.then(function() { return resolve(); })then(resolve) 相同,但无论如何你都不应该这样做。
  • 看起来identyOfferacceptTradeOffer 等已经返回承诺,因为您正在调用then()。对吗?
  • 请添加identyOfferfinishTradeOffer的定义。
  • 我有相同的程序运行良好的回调。我只想迁移到提高我的知识的承诺。我应该返回使用回调吗?

标签: javascript node.js promise resolve


【解决方案1】:

问题是在这个块中:

    } else if (offerState == 'valida') {
        identifyItems(offer).then(function(offerState) {
            finishTradeOffer(offer, offerState);
        })
    }

您没有调用resolve()reject(),因此函数在没有调用任何回调的情况下失败,因此最终,“aqui”块永远不会被调用。

【讨论】:

  • @trincot 你必须调用resolve 才能让promise 执行它的then 回调函数。
  • 我错过了两个函数之间的依赖关系。
  • 不,不是。在 offerState = 'aceptable' 或 'denegable' 之前,我一直在调用相同的承诺。可以吗?
  • 虽然“ok”,但问题是当你递归调用函数时,你仍然需要处理结果。 @torazaburo 中的代码有效,因为它返回递归代码返回的 Promise。如果你没有明确地返回一些东西 - 你会隐含地失败并且什么都不返回。
【解决方案2】:

首先避免使用 Promise constructor antipattern。你的函数已经是返回承诺了。

添加catch 回调以处理可能的错误。

const processTradeOffer = function(offer) {
  return identyOffer(offer)
    .then(function(offerState) {
      return finishTradeOffer(offer, offerState);
    })
    .then(function() {
      console.log('aqui');
    })
    .catch(err => console.log(err));
}

const finishTradeOffer = function(offer, offerState) {
  switch (offerState) {
    case 'aceptable':
      return acceptTradeOffer(offer);
    case 'denegable':
      return declineTradeOffer(offer);
    case 'valida':
      return identifyItems(offer)
        .then(function(offerState) {
          return finishTradeOffer(offer, offerState);
        });
    default:
      return Promise.resolve();
}

【讨论】:

  • 对此我并不太兴奋,因为processTradeOffer 返回的承诺值将是console.log 的返回值,即undefined,而不是来自调用finishTradeoffer,这很可能是我们想要的。并且任何拒绝都将被catch 捕获并转化为成功,再次使用console.log(err) 的值,这不太可能是您想要的。
  • 好的。这对我来说是最好的解决方案。我绝对需要阅读更多关于 Promises 的内容。再问一个问题:acceptTradeOffer 和densureTradeOferr 是异步函数,可能会失败。在那种情况下,错误会被捕获吗?
  • @torazaburo 我同意processTradeOffer 返回一个带有undefined 值的promise,但它是OP 代码,也许他没有使用这个结果。问题是关于为什么不调用 console.log('aqui'); ,我试图描述原因。 catch块呢,我再重复一遍,不知道processTradeOffer函数是怎么用的。如果是独立调用,那么这个catch是有效的。
  • @TomasGonzalez 当然,所有抛出的错误都会在下一个catch 回调中处理。在我的示例中,此回调适用于所有函数。
  • @alexmac 一如既往的好答案!
【解决方案3】:

请按如下方式编写代码。

const processTradeOffer = function(offer) {
  const result = identyOffer(offer)
    .then(offerState => finishTradeOffer(offer, offerState))

  result.then(() =>  console.log('aqui'));

  return result;
 };

const finishTradeOffer = function(offer, offerState) {
  switch(offerState) {
    case 'aceptable': return acceptTradeOffer(offer);

    case 'denegable': {
      const result = declineTradeOffer(offer);
      result.then(() => console.log('here'));
      return result;

    case 'valida':
      return identifyItems(offer)
        .then(offerstate => finishTradeOffer(offer, offerState));

    default: 
      throw "Invalid value for offerstate!!";
  }
};

基本点是处理valida 的情况,以使promise 解决。此外,我们已经摆脱了“显式承诺构造函数反模式”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 2019-04-29
    • 2019-11-18
    • 1970-01-01
    • 2019-07-20
    • 2019-01-25
    • 1970-01-01
    相关资源
    最近更新 更多