2010-04-02 68 views
6

我已經繼承了JavaScript代碼,其中Ajax處理程序的成功回調啓動另一個Ajax調用,其中成功回調可能會或可能不會啓動另一個Ajax調用。這導致深層嵌套的匿名功能。也許有一個聰明的編程模式可以避免深層嵌套,並且更加乾燥。另外,在整個函數中都會使用內部變量myVar1和myVar2。編程模式,以扁平深度嵌套ajax回調?

jQuery.extend(Application.Model.prototype, { 
    process: function() { 
     var myVar1; 
     // processing using myVar1; 
     jQuery.ajax({ 
      url:myurl1, 
      dataType:'json', 
      success:function(data) { 
       var myVar2; 
       // process data using myVar1, set state of myVar2, 
       // then send it back 
       jQuery.ajax({ 
        url:myurl2, 
        dataType:'json', 
        success:function(data) { 
         // do stuff with myVar1 and myVar2 
         if(!data.ok) { 
          jQuery.ajax({ 
           url:myurl2, 
           dataType:'json', 
           success:mycallback 
          }); 
         } 
         else { 
          mycallback(data); 
          } 

        } 
       }); 
      } 
     }); 
    } 
}); 
+1

略有關。使用服務器播放AJAX「ping-pong」是創建額外等待時間的絕對方法。您可能需要考慮是否有可能在一個請求中完成這項工作,即使這意味着要傳輸更多數據。 – aaaaaaaaaaaa 2010-04-02 01:15:29

回答

3

感謝鏈接提示和this comment,我得到了以下解決方案。我已經測試過它,它工作。可能有一些範圍問題,你可以重構一個通用的ChainAjax類。但目前來看,這沒關係。

jQuery.extend(MyApplication.Model.prototype, { 
    process: function() { 

     // private class for executing the Ajax calls 
     var myAjaxCalls = function(options) { 
      this.options = options; 
      this.myVar1 = null; 
      this.myVar2 =null;     
     } 
     jQuery.extend(myAjaxCalls.prototype, { 
      process1:function(data) { 
      // processsing using this.myVar1 
      this.myVar1 = 5; 
      return true; 
      }, 
      process2:function(data) { 
      this.myVar2 = 6;  
      if(data.ok) { 
       mycallback(data); 
      } 
      else { 
       return true; 
      } 
      }, 
      process3:function(data) { 
      // Process this.myVar1 and this.myVar 
      mycallback(data); 
      return false; 
      }, 
      chainAjax:function() { 
      if(this.options.length > 0) { 
       var opt = this.options.shift(); 
       var that = this; 
       jQuery.ajax({ 
       url:opt.url, 
       success:function(data) { 
        if(that[opt.callback](data)) { 
          that.chainAjax(); 
        } 
       } 
       }); 
      } 
      } 
     }); 
     // End private class 

     var calls = new myAjaxCalls([ 
      {url:'http://localhost/', callback:'process1'}, 
      {url:'http://localhost/', callback:'process2'}, 
      {url:'http://localhost/', callback:'process3'} 
     ]); 
     calls.chainAjax(); 
    } 
}); 

更新:我發現this nice presentation也與實用的編程模式和最佳實踐的交易。

更新2012:在此期間有模擬與異步功能的同步流動幾個庫:qstratified.jsstreamline.js

9

沒有必要對所有的回調是匿名和聯定義,你可以在其他地方宣佈他們並指定回調時,只需使用功能名稱。

+0

+1擊敗我。 – 2010-04-02 00:49:14

1

我會建議創建一個名爲「鏈ajax」的小工具。你給它什麼你想要以什麼順序發生,然後開火。它會連鎖成功,直到所有的邏輯用完。它將幫助你不再重複自己,只是代表你想要做的事情與咕嚕編碼的邏輯模型。

0

您可以用Frame.js這樣做:

jQuery.extend(Application.Model.prototype, { 
    process: function() { 
     var myVar1; 
     // processing using myVar1; 
     Frame(function(done){ 
      jQuery.ajax({ 
       url:myurl1, 
       dataType:'json', 
       success: done 
      }); 
     }); 
     Frame(function(done, data) { 
      var myVar2; 
      // process data using myVar1, set state of myVar2, 
      // then send it back 
      jQuery.ajax({ 
       url:myurl2, 
       dataType:'json', 
       success: done 
      }); 
     }); 
     Frame(function(done, data) { 
      // do stuff with myVar1 and myVar2 
      if(!data.ok) { 
       jQuery.ajax({ 
        url:myurl2, 
        dataType:'json', 
        success:done 
       }); 
      } 
      else { 
       done(data); 
      } 
     }); 
     Frame(function(done, data){ 
      mycallback(data); 
     }); 
     Frame.start(); 
    } 
});