2016-07-23 42 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鏈接。 –