多个jQuery ajax请求的链接

5

我有以下代码:

$.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');
                });

            });

        });

    });

当使用when.apply()时,传递给它的每个函数都会返回请求数组。由于这些调用依赖于从loadProjects()返回的信息,所以我无法在loadProjects()调用完成之前执行buildRequests调用。每个调用依赖于前一个调用返回的信息,因此必须按照此顺序进行。我需要知道所有调用何时完成,以便我可以处理返回的数据。

有更清晰的方法来处理这个问题吗?


看起来你有很多请求需要链接。我建议将所有请求合并成一个,这比链接更高效。 - Jovan Perovic
我该怎么做呢?由于我使用的API,我必须一个接一个地调用。 - JFoulkes
我发布了如何实现这个的答案,因为评论不太喜欢代码格式 :) - Jovan Perovic
我认为这个答案中的示例非常有用,可以帮助理解管道的概念:jquery-ajax multiple calls - blong
3个回答

2

我前几天发现了 yepnope.js。虽然我自己还没有尝试过,但如果你需要经常进行ajax加载,它可能会有所帮助。


实际上,仔细考虑后,我意识到yepnope.js并不适用于你的情况。在你的情况下,我会考虑让 loadProjects() 等函数在内部应用 when() 来返回单个 Promise。此外,使用 pipe() 也可以得到类似以下的结果:

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

示例 buildRequests()

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

    var requestsPromise = ...; // Finally get ajax promise for requests
    return requestPromise;
}
requestPromise 的结果在解决/拒绝后,将被传递到下一个管道函数中。
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
});

你有没有这方面的样例或链接?我对 deferred/promise 这些完全不熟悉。 - JFoulkes
增加了一个函数的示例。其他函数类似。有关其工作原理的更多信息,请参见链接.pipe() - Supr
我知道管道将会有所帮助,我现在唯一的问题是如何让它与每个函数返回的动态请求数量配合工作... - JFoulkes
如果您不需要等待每个请求的响应,那么可以将它们包装在 when() 中,然后在消费者中执行 function buildRequests(){var projects = arguments; /* then do something with projects, etc. */}。内置的 arguments 变量包含传递给函数的所有参数,而 when() 将传递每个项目承诺的结果。 - Supr

2

AJAX请求的依赖链:您可以链接多个AJAX请求 - 例如,第一次调用检索用户的详细信息,我们需要将该值传递给第二个脚本。请记住,$.then()返回一个新的Promise,随后可以传递给$.done()甚至另一个$.then()方法。

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

1

根据我的原帖评论回复如下:

看起来您有很多需要链接的请求。那么我会考虑将所有请求合并为一个...比链接更有效率...

嗯,类似这样:

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

这样,您就可以在调用之间具有固有的同步性,并且减少HTTP流量;)


我没有使用除 JavaScript 之外的任何意图。 - JFoulkes
好的,但是那些 AJAX 请求会调用一些服务器端脚本,无论是 PHP 还是其他任何语言,不是吗? - Jovan Perovic
它们是对我无法控制的API的ajax请求。 - JFoulkes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接