2016-05-12 71 views
0

我似乎遇到了典型的“异步问题”,解决方案无法解决。暂停函数执行流程直到ajax请求完成

我有一个bootstrap form wizard这只是一个即兴创作的标签/幻灯片有点儿。我所有的“步骤”都是各自标签页/幻灯片中的表单。

它有一组下一个/上一个按钮来浏览幻灯片。 它在移动到下一张幻灯片之前提供函数回调。 里面(回调)我是“客户端验证”在当前幻灯片的形式,如果验证,然后我提交表单使用Ajax。一旦我得到服务器的响应,我决定是否返回true(继续下一张幻灯片)或返回false(停止导航到下一张幻灯片)。

我已经调查..

  • Using callbacks但随后它不会从出发到下一个幻灯片,这是顺便说一句硬编码的成功消息停止插件,所以当我们在等待Ajax响应向导已经转移到下一张幻灯片。
  • 使用async:false,但这挂在浏览器像疯了(设计),直到请求完成,所以没有挂这正是我想要的。

我的代码如下所示。

JS。

jQuery('#progressWizard').bootstrapWizard({ 
      'nextSelector': '.next', 
      'previousSelector': '.previous', 
      onNext: function (tab, navigation, index) { 
       if (index == 1) { // Here I am deciding which code to execute based on the current slide/tab (index) 
        if (jQuery("#paymentstep1").data('bValidator').validate()) { 
         var data = new FormData(jQuery('#paymentstep1')[0]); 
         jQuery("#cgloader").fadeIn(); 
         var success = false; 
         jQuery.ajax({ 
          type: "post", 
          async: false, 
          contentType: false, 
          processData: false, 
          url: "xyz.php", 
          dataType: "json", 
          data: data, 
          success: function (r) { 

           return r; 
          } 
          }); 
         }.... 
+0

第一种方法是唯一的真正可接受的解决方案。如果这意味着更改向导插件,我仍然强烈推荐它。使用'async:false'永远不会成为一种选择,因为如你所见,它会挂起浏览器直到请求完成。这会让浏览器看起来像是崩溃的用户,这是糟糕的用户体验。解决方法是使用异步请求。 –

+0

停止导航到下一张幻灯片,然后在回调中重新启动它 –

回答

3

docsonNext说:

燃煤点击下一步按钮时(返回false禁用 移动到下一个步骤)

所以,简单地从返回false您处理程序。在AJAX成功回调中,请致电next前进到下一张幻灯片。

var requestCompleted = false; 
jQuery('#progressWizard').bootstrapWizard({ 
    'nextSelector': '.next', 
    'previousSelector': '.previous', 
    onNext: function (tab, navigation, index) { 
    if (index == 1) { // Here I am deciding which code to execute based on the current slide/tab (index) 
     if (jQuery("#paymentstep1").data('bValidator').validate()) { 
     if(!requestCompleted) { 
      var data = new FormData(jQuery('#paymentstep1')[0]); 
      jQuery("#cgloader").fadeIn(); 
      var success = false; 
      jQuery.ajax({ 
       type: "post", 
       url: "xyz.php", 
       data: data, 
       // ... 
       success: function (r) { 
       requestCompleted = true; 
       jQuery('#progressWizard').bootstrapWizard('next'); 
       return r; 
       } 
      }); 
      return false; 
     } 
     } 
    } 
    }); 
+0

我的想法正好 –

+0

但是,如果我在下一个Ajax成功的内部调用,那么“onNext”回调中的代码是不是会重新触发?再次发出ajax请求? –

+0

当然。因此,请使用变量来跟踪您是否提出了请求。 –

1

我会用不同的事件来执行你的异步代码。这个想法是使用onTabChange(考虑使用onTabClickonTabShow),以防止移动到下一个选项卡bootstrapWizard();如何导航。只有在所有事情都以编程方式触发下一个标签之后,你必须找出如何。

$('element').bootstrapWizard('onTabShow', function(){ 

    //Do everything you need here and show next tab 
    $('element').bootstrapWizard('show',3); 
    return false; 
}); 
1

使用承诺?

在jQuery中有承诺。这是语法。

$.when($.ajax("test.aspx")).then(function(data, textStatus, jqXHR) { 
    alert(jqXHR.status); }); 

现在JavaScript中也有承诺!

var promise = new RSVP.Promise(function(fulfill, reject) { 
    (...) 
}); 

然后,

promise.then(onFulfilled, onRejected); 
相关问题