2016-07-23 7 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 
}) 

はピラミッドの-破滅を避けるために。

しかし、上記のコードでは、が早く解決し、$$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

ピラミッドを作ることについてあまり心配しないでください。

ピラミッドは常に避けられないで、許可することができます:ピラミッドでクロージャを利用して特定のエラー

を引く閉鎖

  • て以前の結果に

    • アクセス、あなたは一般的に必要性を回避します外側のvar(あなたのglobalVar)のため、作業バージョンでは、ピラミッドと外側のvarの両方を見るのは驚くべきことです。

      特定の問題が明白でないほどコードが簡略化されているため、さらにアドバイスすることは困難です。 globalVarの必要性ははっきりしておらず、ピラミッドは正常に平坦化されたように見えます。 some logicブロックで何かが起こっている可能性があります。または、finalyAsync()にはreturnがありません。

  • +0

    ああ、私はそれをすべて擬似的にコーディングしていたので、2番目のバージョンではグローバルを残しました。ストライプの呼び出しと関係しているかもしれないと思うかもしれませんが、 'setTimeout(){resolve()} 'があっても失敗しています。これは巨大な約束木の一部なので、それほど悪くないわけではありません。わずかなピラミッドでさえ。私はなぜJSBINの作業バージョンを投げようとしています。しかし、なぜそれが何をしているのか分かりません。ありがとう! – tr3online

    +0

    OK、JSBINリンクを待っています。 –

    関連する問題