2010-04-02 37 views
6

Tôi đã kế thừa mã JavaScript nơi lời gọi thành công của trình xử lý Ajax khởi tạo một cuộc gọi Ajax khác, nơi cuộc gọi lại thành công có thể hoặc không thể khởi tạo một cuộc gọi Ajax khác. Điều này dẫn đến các chức năng ẩn danh lồng nhau sâu sắc. Có thể có một mô hình lập trình thông minh giúp tránh làm tổ sâu và nhiều DRY hơn. Ngoài ra, có sự cố của các biến bên trong myVar1 và myVar2 được sử dụng trong suốt các hàm.Mô hình lập trình để làm phẳng các callback ajax lồng nhau sâu sắc?

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

Hơi liên quan. Chơi AJAX "ping-pong" với máy chủ là một cách chắc chắn để tạo thêm thời gian chờ đợi. Bạn có thể muốn xem xét nếu nó có thể thực hiện công việc chỉ trong một yêu cầu, ngay cả khi điều đó có nghĩa là truyền tải nhiều dữ liệu hơn. – aaaaaaaaaaaa

Trả lời

3

Nhờ gợi ý chuỗi và this comment, tôi đã đi đến giải pháp sau. Tôi đã thử nghiệm nó và nó hoạt động. Có lẽ một số vấn đề phạm vi và bạn có thể cấu trúc lại một lớp ChainAjax chung ra khỏi nó. Nhưng trong thời gian này, điều này là ok.

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

Cập nhật: tôi thấy this nice presentation mà cũng giao dịch với mô hình lập trình hữu ích và thực hành tốt nhất.

Cập nhật 2012: Trong khi đó có một số thư viện cho mô phỏng một dòng chảy đồng bộ với các chức năng không đồng bộ: q, stratified.jsstreamline.js

9

Không cần tất cả các cuộc gọi lại là ẩn danh và được xác định nội tuyến, bạn có thể khai báo ở nơi khác và chỉ sử dụng tên hàm khi chỉ định gọi lại.

+0

+1 Đánh tôi với nó. –

1

Tôi khuyên bạn nên tạo một công cụ nhỏ gọi là "chuỗi ajax". Bạn cho nó những gì bạn muốn xảy ra theo thứ tự nào, và sau đó bắn. Nó sẽ chuỗi ajax thành công cho đến khi tất cả các logic chạy ra ngoài. Nó sẽ giúp bạn ngừng lặp lại chính mình và chỉ đại diện cho mô hình logic của những gì bạn muốn thực hiện vs grunt-coding.

0

Bạn có thể làm điều này với Frame.js như thế này:

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(); 
    } 
}); 
Các vấn đề liên quan