2012-02-10 46 views
5

Tôi có đoạn mã sau:Chaining nhiều jQuery ajax yêu cầu

$.when(loadProjects()) 
    .then(function() { 

     $.when.apply($, buildRequests(projects)) 
     .then(function(data) { 

      $.when.apply($, vcsRequests(buildTypes)) 
      .then(function(data) { 

       $.when.apply($, vcsDetailRequests(vcsRoots)) 
       .then(function(data) { 
        alert('done'); 
       }); 

      }); 

     }); 

    }); 

Mỗi phòng trong số các chức năng thông qua vào when.apply() mảng trở lại của yêu cầu. Tôi không thể thực hiện các cuộc gọi buildRequests cho đến khi các cuộc gọi từ loadProjects() đã kết thúc khi họ dựa vào thông tin được trả về từ các cuộc gọi đó. Mỗi cuộc gọi phụ thuộc vào thông tin được trả về bởi cuộc gọi trước đó, vì vậy chúng phải theo thứ tự này. Tôi cần biết khi nào tất cả các cuộc gọi đã kết thúc để tôi có thể xử lý dữ liệu được trả lại.

Có cách nào tiếp cận rõ ràng hơn không?

+0

Dường như bạn có nhiều yêu cầu để chuỗi. Sau đó tôi sẽ xem xét kết hợp tất cả các yêu cầu vào một duy nhất .... hiệu quả hơn nhiều so với chuỗi ... –

+0

Làm thế nào tôi sẽ đi về làm điều đó? Tôi phải gọi cái khác vì API tôi đang sử dụng. – JFoulkes

+0

Tôi đã đăng câu trả lời về cách đạt được điều này vì nhận xét không thực sự thích định dạng mã :) –

Trả lời

2

Tôi đã xem qua yepnope.js vào ngày khác. Tôi chưa thử nó, nhưng nó có thể hữu ích nếu bạn đang làm rất nhiều ajax tải.


Thực tế suy nghĩ điều này khiến tôi nhận ra rằng yepnope.js không thực sự áp dụng cho trường hợp của bạn. Những gì tôi sẽ xem xét trong trường hợp của bạn là để có loadProjects() et al trả lại một lời hứa bằng cách áp dụng when() nội bộ trong mỗi chức năng. Cũng đặt pipe() sử dụng có thể dẫn đến một cái gì đó giống như

loadProjects().pipe(buildRequests).pipe(vcsRequests).pipe(vcsDetailRequests); 

mẫu buildRequests():

function buildRequests(projects){ 
    // Do something using projects 
    // ... 

    var requestsPromise = ...; // Finally get ajax promise for requests 
    return requestPromise; 
} 

Kết quả của requestPromise sau đó sẽ được chuyển vào chức năng đường ống tiếp theo một khi nó đã được giải quyết/từ chối.


Từ các tài liệu trên pipe():

// Example: Chain tasks: 

var request = $.ajax(url, { dataType: "json" }), 
    chained = request.pipe(function(data) { 
     return $.ajax(url2, { data: { user: data.userId } }); 
    }); 

chained.done(function(data) { 
    // data retrieved from url2 as provided by the first request 
}); 
+0

Bạn có bất kỳ mẫu/liên kết nào về cách thực hiện việc này không? Tôi là người mới đối với toàn bộ công cụ được giải đáp/hứa hẹn – JFoulkes

+0

Đã thêm mẫu của một trong các chức năng. Những người khác sẽ là tương tự. Xem liên kết đi kèm với ['.pipe()'] (http://api.jquery.com/deferred.pipe/) để biết thêm về cách nó hoạt động. – Supr

+0

Tôi thấy cách ống sẽ giúp, vấn đề duy nhất tôi có bây giờ là làm cho công việc này với số lượng động yêu cầu mà mỗi chức năng trả về ... – JFoulkes

1

.... phản ứng theo nhận xét của tôi về bài đăng gốc:

Có vẻ bạn có rất nhiều yêu cầu để chuỗi. Sau đó tôi sẽ xem xét kết hợp tất cả yêu cầu thành một đơn .... nhiều hơn nữa hiệu quả hơn chaining ...

Vâng, một cái gì đó như thế này:

PHP: 
$projects = YourAPI::loadProjects(); 
$builds = YourAPI::getBuilds($projects); 
$vcs = YourAPI::getVCS($builds); 
$details = YourAPI::getVCSDetails($vcs); 

// for example 
return json_encode($details); 

// OR, if you need all the data 
$results = array( 
    "projects" => $projects, 
    "builds" => $builds, 
    "vsc" => $vcs, 
    "details" => $details 
); 
return json_encode($results); 

Bằng cách này, bạn có synhronization cố hữu giữa các cuộc gọi VÀ ít HTTP trafiic;)

+0

Tôi không có ý định sử dụng bất kỳ thứ gì ngoài javascript – JFoulkes

+0

oook, nhưng những yêu cầu ajax đó gọi một số tập lệnh phía máy chủ, có thể là PHP hay bất kỳ ngôn ngữ nào khác, phải không? –

+0

Chúng là yêu cầu ajax đối với API mà tôi không kiểm soát được – JFoulkes

1

Chuỗi phụ thuộc yêu cầu AJAX: Bạn có thể chuỗi nhiều yêu cầu AJAX - ví dụ: cuộc gọi đầu tiên truy xuất chi tiết người dùng của người dùng và chúng ta cần chuyển giá trị đó cho tập lệnh thứ hai. Hãy nhớ rằng $.then() trả về một lời hứa mới, sau đó có thể được chuyển đến $.done() hoặc thậm chí một phương thức $.then() khác.

var a1 = $.ajax({ 
      url: '/first/request/url', 
      dataType: 'json' 
     }), 
    a2 = a1.then(function(data) { 
      // .then() returns a new promise 
      return $.ajax({ 
       url: '/second/request/url', 
       dataType: 'json', 
       data: data.userId 
      }); 
     }); 

a2.done(function(data) { 
    console.log(data); 
}); 
Các vấn đề liên quan