2016-05-12 17 views
0

私は典型的な "非同期問題"に遭遇しているようですが、解決策がわかりません。ajaxリクエストが完了するまで関数の実行フローを一時停止する

私はbootstrap form wizardを持っています。これはただの即興のタブ/スライドショーのようなものです。すべての私の「ステップ」はそれぞれのタブ/スライドの中にそれぞれのフォームです。

スライドの前後に移動するための一連の[次へ]/[前へ]ボタンがあります。 そして関数コールバックに提供する前に、を次のスライドに移動します。 (コールバック)内部で、現在のスライドのフォームを「クライアント側で検証していますか?」と検証されていれば、フォームをajaxで送信しています。サーバーからの応答を取得したら、trueを返すか(次のスライドに進む)、falseを返すかを決定します(次のスライドへのナビゲーションを停止します)。

私は..

  • Using callbacksに見てきたが、我々はAJAXの応答をウィザードを待っている間ので、それは文句を言わない、ところで、ハードコーディングされた成功のメッセージで次のスライドに進むからプラグインを停止すでに次のスライドに移動しました。
  • async:falseを使用していますが、リクエストが完了するまでブラウザがクレイジー(設計上)のようにハングするので、これはまさに私が望むものです。

私のコードは以下の通りです。

JS。次のボタンがクリックされたときに

は解雇(次のステップに移動 を無効にする場合はfalseを返す)

だから、単にあなたからfalseを返す:onNextためdocsが言う

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'を使用することは決して選択肢ではありません。あなたが見てきたように、要求が完了するまでブラウザをハングするからです。これにより、クラッシュしたようなブラウザがユーザに見えるようになります。これはひどいUXです。この問題を回避するには、非同期要求を使用します。 –

+0

次のスライドへのナビゲーションを停止し、コールバックで再起動 –

答えて

3

ハンドラ。 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

私は非同期コードを実行するために異なるイベントを使用します。考え方は、(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); 
関連する問題