1

次のような関数があります。

function showCreditCard(idx, data) {

    if(typeof cardInfo == 'undefined' && parseInt($("#cc-dropdown-" + idx + " option:selected").val(),10) > -1) {
       // actual selection made, but not default, so cardInfo hasn't been set. Need to run ajax call to get credit card;
       console.log("show dropdown");
       console.log("there are saved cards and a selection was made");
       poGetPaymentOption('credit card', parseInt($("#cc-dropdown-" + idx + " option:selected").val(),10), idx);

        // this is the default card; display dropdown with default selected and static fields
        console.log("supposedly after poGetPayment");
        console.dir(cardInfo);

        // why is this stuff running before poGetPaymentOtion finishes and returns a cardInfo object?
        if( cardInfo.cc.cc_type == 'VI' ) { $('#cc_visaBig-'+idx).attr('class', 'cc_visaBig'); }

        $('#cc-static-wrap-'+idx).show();
        updateButtonState();

    }

}

コメントからわかるようpoGetPaymentOptionに、関数が実際に完了する前に、呼び出しの後の行が実行されています。関数のログでもこれを確認しましたpoGetPaymentOption(以下)。

function poGetPaymentOption(type, key, bIdx) {
   if( type == 'credit card' ) {
      console.log("signed in, credit card");
      $.post('/site/ajax/customers/getSingleCreditCard',
          { 'key': key },
          function(data) {
            if( data.success == 1 ) {
                console.log("poPayment success");
                    if(typeof cardInfo == 'undefined') {
                        cardInfo = new saveCardInfo(data);
                    }    

            } else {
              console.log("poPayment no success");
            }
          }, 'json');
    } 
}

私が期待するのは、からの呼び出しshowCreditCardpoGetPaymentOptionajax 呼び出しを介して成功を返し (それが行う)、 という新しいsaveCardInfoオブジェクトを作成することcardInfoです。私が知る限り、それは起こりcardInfo.cc.cc_typeますが、オブジェクトが作成される前に行のチェックとそれ以降のすべてが行われます。Firebug コンソールのスクリーンショットを添付したので、物事が起こっている順序は明らかです。

ここに画像の説明を入力

私は何を間違っていますか?関数をさらに続行する前にpoGetPaymentOption、完全に作成されていることを確認する必要があります。cardInfoshowCreditCard

4

2 に答える 2

1

AJAX 呼び出しは非同期であるため、すぐにではなく、応答が到着したときに成功コールバック関数が呼び出されます。

実際、コードの実行中は、応答が到着したときに発生するイベントを処理できません。関数を終了する前に応答が届いた場合でも、showCreditCard関数を終了するまでイベントは処理されないため、関数を終了するまでコールバックは呼び出されませんshowCreditCard

フェッチされたデータを利用するには、成功のコールバック関数でそれを行う必要があります。コードをその関数に移動するか、コールバック関数を に送信してpoGetPaymentOption、応答が到着したときに呼び出すことができるようにします。

(完全を期すために、代わりに同期呼び出しを行うと、コードを再配置せずに機能させることができますが、応答を待っている間にブラウザーがフリーズするため、お勧めできません。)

于 2013-03-20T22:55:43.120 に答える
0

これは、$.post()非同期で実行されるために発生します。

基本的に、JSコードは、AJAX呼び出しがサーバーに送信されている間同期を継続します。サーバーが応答した場合にのみ、コールバック関数が実行されます。

正確な例では、その後のすべてpoGetPaymentOption('credit card', parseInt($("#cc-dropdown-" + idx + " option:selected").val(),10), idx);が無名関数が実行される前に実行されます。

      function(data) {
        if( data.success == 1 ) {
            console.log("poPayment success");
                if(typeof cardInfo == 'undefined') {
                    cardInfo = new saveCardInfo(data);
                }    

        } else {
          console.log("poPayment no success");
        }
      }

showCreditCardこれを修正するには、コールバック内で残りの関数を移動する必要があります。または、コールバック内で呼び出される別の関数を作成します。

于 2013-03-20T22:54:01.963 に答える