凌乱的运营秩序问题

时间:2013-03-20 22:49:15

标签: javascript operator-precedence

我有一个看起来像这样的函数:

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调用(它执行)返回成功,然后创建一个名为{的新saveCardInfo对象{1}}。据我所知,确实发生了这种情况,但检查cardInfo及以后的行都是在创建对象之前发生的。我附上了我的Firebug控制台的屏幕截图,所以很明显订单正在发生。

enter image description here

我做错了什么?我需要确保cardInfo.cc.cc_type已完全填写并且poGetPaymentOption已创建,然后再继续cardInfo功能。

2 个答案:

答案 0 :(得分:1)

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

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

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

(为了完整性;进行同步调用会使代码工作而不重新排列,但不建议在浏览器等待响应时冻结它。)

答案 1 :(得分: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函数。或者创建另一个在回调中调用的函数。