2013-03-20 144 views
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'); 
    } 
} 

我會希望發生的是呼叫從showCreditCardpoGetPaymentOption通過AJAX調用返回成功(其它),然後創建一個名爲cardInfosaveCardInfo對象。據我所知,它確實發生,但是檢查cardInfo.cc.cc_type及更高版本的行都是在創建對象之前發生的。我附上了我的Firebug控制檯的屏幕截圖,因此很明顯,訂單事情正在發生。

enter image description here

我在做什麼錯?我需要確保poGetPaymentOption已完全完成,並且在繼續執行showCreditCard函數之前已創建了cardInfo

+1

使用$就不是$。發佈並將async設置爲false。 – Cristy 2013-03-20 22:52:45

+0

當poGetPaymentOption()結束時,您需要執行第一個方法的其餘部分。你需要一個回調函數。 – 2013-03-20 22:54:06

+3

@Cristy:不,儘管可能,但這不可取。 – Bergi 2013-03-20 22:54:15

回答

1

AJAX調用是異步的,所以成功回調函數將在響應到達時調用,而不是立即調用。

實際上,當您的代碼運行時,響應到達時發生的事件無法處理。即使響應在您退出showCreditCard函數之前到達,在您退出函數之前該事件也不會被處理,因此直到您退出showCreditCard函數後纔會調用該回調函數。

爲了利用獲取的數據,您需要在成功回調函數中執行該操作。將代碼移入該函數,或將回調函數發送到poGetPaymentOption,以便在響應到達時進行調用。

(出於完整性;進行同步調用,而不是將讓你的代碼工作沒有清理它,但因爲它凍結瀏覽器,同時它的等待響應這是不可取的。)

+0

我不確定我明白我應該移入成功回調的代碼。 'showCreditCard'中的所有代碼?這是行不通的。我在這裏展示的是該函數的精簡版本;它實際上在多個地方被調用,並且裏面有各種各樣的條件 - 並不是所有的條件都依賴於'poGetPayment',所以我不能將所有的代碼移入它,而不需要在其他地方複製它,所以它可以在其他情況下被調用。 – EmmyS 2013-03-21 01:37:29

+0

@EmmyS:您只需移動依賴AJAX調用結果的代碼即可。你可以在'showCreditCard'中將這段代碼放在一個回調函數中,它可以讓代碼保持在同一個地方,但是從程序流的角度來看,代碼是在一個單獨的函數中。 – Guffa 2013-03-21 08:38:10

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功能。或者,也可以創建另一個在回調中被調用的函數。