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');
    } 
}

我期望发生的是调用 from showCreditCardtopoGetPaymentOption通过 ajax 调用返回成功(它确实如此),然后创建一个saveCardInfo名为cardInfo. 据我所知,它确实发生了,但是检查cardInfo.cc.cc_type和超越的行都是在创建对象之前发生的。我附上了我的 Firebug 控制台的屏幕截图,所以事情发生的顺序很明显。

在此处输入图像描述

我究竟做错了什么?在继续使用该功能之前,我需要确保它poGetPaymentOption已完全完成并cardInfo已创建。showCreditCard

4

2 回答 2

1

AJAX 调用是异步的,所以成功回调函数将在响应到达时调用,而不是立即调用。

实际上,当您的代码运行时,无法处理响应到达时发生的事件。即使响应在您退出函数之前到达,在您退出showCreditCard函数之前不会处理事件,因此在您退出showCreditCard函数之前永远不会调用回调。

要使用获取的数据,您需要在成功回调函数中执行此操作。将代码移动到该函数中,或者将回调函数发送到 中poGetPaymentOption,以便在响应到达时调用它。

(为了完整性;进行同步调用将使您的代码无需重新排列即可正常工作,但不建议这样做,因为它会在等待响应时冻结浏览器。)

于 2013-03-20T22:55:43.120 回答
0

发生这种情况是因为$.post()异步执行。

基本上,当 AJAX 调用转到服务器时,您的 JS 代码会同步继续。只有当服务器响应您的回调函数时才会执行。

在您的确切示例中,之后的所有内容都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 回答