2010-05-12 31 views
5

Các cuộc gọi không đồng bộ tuần tự là tổng. Có giải pháp dễ đọc hơn không?Làm cách nào để tránh các hàm lồng nhau khi sử dụng AJAX?

Vấn đề là đây là khó để làm theo:

ajaxOne(function() { 
    // do something 
    ajaxTwo(function() { 
    // do something 
    ajaxThree() 
    }); 
}); 

nơi các chức năng ẩn danh là callbacks được kêu gọi phản ứng máy chủ.

Tôi đang sử dụng API của bên thứ ba để thực hiện cuộc gọi AJAX, vì vậy tôi cần giải pháp chung.

Trả lời

3

lập trình chức năng để giải cứu! jsdeferred cho phép bạn viết ví dụ của bạn như sau:

next(ajaxOne).next(ajaxTwo).next(ajaxThree).error(function(e){alert('An error happened:' + e)}) 

mỗi "tuần tự" ajaxOne/Hai/Ba chức năng nhận được kết quả trả về của người tiền nhiệm của nó như là tham số. Nếu bạn cần truyền các tham số bổ sung, bạn có thể phơi bày chúng trong một đối tượng chung trước khi bạn gọi chuỗi ajax của mình.

+0

Mặc dù cách tiếp cận đó có nhiều nỗ lực hơn để làm, nhưng nó chắc chắn rất đẹp và sạch sẽ :) Nhưng nó không thực sự là vấn đề "lập trình chức năng". – selfawaresoup

+0

Điều này trông thật sự tuyệt vời, nhưng tôi không thể tìm ra cách lớp học hoãn lại hoạt động trong nội bộ. –

+0

Một cái nhìn tại nguồn của jsdeferred (http://github.com/cho45/jsdeferred/blob/master/jsdeferred.js) cho bạn biết rằng hàm tiếp theo chỉ đợi cuộc gọi ajax đầu tiên đến (sử dụng setTimeout) và sau đó gửi tiếp theo. – fbuchinger

1

Nếu bạn chỉ có một hàm lồng nhau, bạn có thể để nguyên nó, nhưng nếu bạn có nhiều cuộc gọi lồng nhau, bạn nên cân nhắc viết các cuộc gọi lại này bằng một phương thức riêng và gọi nó từ hàm lồng nhau ...

ajaxOne(function(result) { handleAjaxOneCallback(result, someExtraNeededArg); }); 

function handleAjaxOneCallback(result, someExtraNeededParam) { 
    // do something 

    ajaxTwo(function(result) { handleAjaxTwoCallback(result, myFoo, myBar); }); 
} 

function handleAjaxTwoCallback(result, foo, bar) { 
    // do something 

    ajaxThree(/* ... */); 
} 
0

Nếu bạn không cần phạm vi đóng cửa trong các cuộc gọi lại, bạn có thể không, bạn chỉ có thể đặt các hàm gọi lại thành các chức năng riêng biệt và gọi chúng theo tên của chúng. như:

var ajaxOne = function() { 
    doTheAjax(callbackOne); 
} 
var callbackOne = function() { 
    //funny things ... 
    doTheAjax(callbackTwo); 
} 
var callbackTwo = function() { 
    //even more funny things ... 
} 
+0

Câu hỏi của tôi có thể đã được hình thành kém. Đây thực sự là phương pháp tôi sử dụng như là dòng sẽ nhận được cách quá lớn trong ví dụ của tôi. Tuy nhiên, logic rất khó để theo dõi bởi vì các cuộc gọi vẫn phải được truy tìm. –

1

Trước tiên, tôi phải thừa nhận, tôi tương đối mới với JavaScript, nhưng gần đây tôi đã gặp phải cùng một vấn đề trong khi sử dụng chức năng jQuery ajax. Tôi phải tải lên một vài tài liệu qua POST tới máy chủ theo một thứ tự nhất định. Làm tổ tất cả các cuộc gọi lại sẽ tạo ra mã hoàn toàn sai lầm. Tôi nghĩ về một giải pháp sau khi đọc các câu trả lời và đưa ra một giải pháp làm việc tốt cho tôi. Nó chỉ sử dụng một hàm có mệnh đề chuyển đổi để phân biệt các lời gọi lại khác nhau:

var callback = function(sCallIdentifier, callbackParameters){ 
    switch(sCallIdentifier){ 
    case "ajaxOne": 
     doYourStuff(callbackParameters); //do your stuff for ajaxOne 
     ajaxTwo(function(newCallbackParameters){ 
      /*define a anonymous function as actual method-callback and pass the call-identifier, together with all parameters, to your defined callback function*/ 
      callback("ajaxTwo", newCallbackParameters); 
     }); 
     break; 
    case "ajaxTwo": 
     doYourStuff(callbackParameters); 
     ajaxThree(function(newCallbackParameters){ 
      callback("ajaxThree", newCallbackParameters); 
     }); 
     break; 
    case "ajaxThree": 
     doYourStuff(); 
     break; 
} 
}); 

Nếu đây không phải là ý hay, hãy cho tôi biết. Như tôi đã nói, tôi không phải là chuyên gia về JavaScript nhưng tôi đã làm việc rất tốt cho tôi.

nhất, René

Edit:

Sau một thời gian tôi phát hiện ra rằng Promises là một cách tiếp cận tốt hơn để giải quyết vấn đề này.

Các vấn đề liên quan