2016-07-23 51 views
1

我试图做一些承诺链使用角度的执行$q,但似乎已经遇到了几乎被迫进入金字塔的厄运局面的路障。

我宁愿做:

function doYetAnotherAsync() { 
    return $q(function(resolve, reject){ 
     var transaction = { 
      cvc: vm.cvc, 
      exp_year: vm.expirationYear, 
      exp_month: vm.expirationMonth, 
      number: vm.cardNumber 
     } 
     Stripe.card.createToken(transaction, function(responseCode, response) { 
      console.log('createToken'); 
      if(responseCode === 200) { 
       resolve({ 
        id: core.get(response, 'id'), 
        cardId: core.get(response, 'card.id') 
       }); 
      } 
      reject(response); 
     }); 
    }); 
} 

function doAnotherAsync() { 
    return $q(function(resolve, reject){ 
     var globalVar; 
     doSomeNormalAjaxCall() 
     .then(function(response){ 
      globalVar = response.id; 
      return doYetAnotherAsync() 
     }) 
     .then(function(stripeData){ 
      console.log('stripeData', stripeData); 
      // stripeData returns a $$state object 
      return finalAsync() 
     }) 
     .then(function(response){ 
      // handle final data here 
      // resolve/reject $q 
     }) 
    }) 
} 

doSomeAsync() 
.then(doAnotherAsync) 

请注意,在doAnotherAsync(),我很想能够使用这种形式:

someAsync() 
.then(function(){ 
    return someOtherAsync() 
}) 
.then(function(){ 
    return yetAnotherAsync() 
}) 
.then(function(){ 
    // finally do some stuff 
}) 

为了避免金字塔的-厄运。

但是,在上面的代码中,第二个.then()解决得很早,一个$$state对象沿着链传递,而不是正常对象{id: '', cardId: ''}

console.log命令举例:

stripeData d {$$state: Object} 
XHR finished loading: POST "https://api.stripe.com/v1/tokens" 
createToken 

要保留链接的承诺订单和获得真正的对象的反应,我不得不做的事:

function doAnotherAsync() { 
    return $q(function(resolve, reject){ 
     var globalVar; 
     doSomeNormalAjaxCall 
     .then(function(response){ 
      globalVar = response.id; 
      return doYetAnotherAsync() 
      .then(function(stripeData){ 
       // some logic 
       return finalyAsync() 
      }) 
     }) 
     .then(function(response){ 
      // final processing 
     }) 
    }) 
} 

缺少什么我在这里?

+1

它绝对可以解决。 'globalVar'的作用是什么? “doSomeNormalAjaxCall”究竟是什么,它是jQuery吗?从它返回的承诺有问题。一个承诺不能将不确定的承诺传递给下一代(“尽早解决”),$ q和本地承诺是合规的,不会这样做。 – estus

回答

0

不要太担心制作金字塔。

金字塔并不总是可以避免的,可以允许:

  • 访问以前的结果通过关闭
  • 捕捉特定的错误

通过在金字塔利用关闭,您通常会避免需要对于外部变量(你的globalVar),所以在工作版本中,看到一个金字塔和一个外部变量是令人惊讶的。

由于代码已被简化为特定问题未公开,因此很难进一步提出建议。 globalVar的需求尚不清楚,金字塔看起来应该成功地变平。 some logic区块可能正在发生什么,或者finalyAsync()中有可能是return

+0

嗯,我伪编码所有,所以我离开了全球第二版,绝对不需要它,谢谢你的提示。我想也许它与Stripe调用有关,但即使使用'setTimeout(){resolve()}'也会失败。这是一个巨大的承诺树的一部分,所以它不差。即使有一个轻微的金字塔。我会试着在JSBIN上抛出一个工作版本来看看为什么。尽管如此,我无法弄清楚为什么它在做这件事。谢谢! – tr3online

+0

好的,我会等待JSBIN链接。 –