jQuery,带有URL数组的$ .ajax [英] jQuery, $.ajax with array of urls

查看:64
本文介绍了jQuery,带有URL数组的$ .ajax的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的网址数组,我想用jQuery加载每个网址.我使用的是$.get,但似乎无法使其与$.Deferred一起使用,因此我切换到了$.ajax-我几乎可以使用它了,但是得到的结果却很奇怪.我希望有人能帮助我更好地完成这项工作.

I have a simple array of urls, and I want to load each one with jQuery. I was using $.get, but I cannot seem to get it to work with $.Deferred, so I switched to $.ajax - I almost have it working, but the results I am getting are .. odd. I was hoping someone could help me make this work better.

var results = [], files = [
   'url1', 'url2', 'url3'
];

$.when(
   $.ajax(files[0]).done(function(data) { 
      results.push(data); console.log("step 1.0"); 
   }),
   $.ajax(files[1]).done(function(data) { 
      results.push(data); console.log("step 1.1"); 
   }),
   $.ajax(files[2]).done(function(data) {
      results.push(data); console.log("step 1.2"); 
   })
).then(function(){
   console.log("step 2");
});

这应该输出.

  • 步骤1.0
  • 步骤1.1
  • 步骤1.2
  • 第2步

然后results数组包含所有3个ajax请求的结果.这可能吗?

And then the results array contains the result of all 3 ajax requests. Is this possible?

推荐答案

首先,您必须确定是否要并行处理三个ajax调用(同时运行所有ajax调用,而总运行时间较少)或按顺序执行一个Ajax调用,然后完成,然后启动下一个Ajax调用.这是一个关键的设计决策,会影响您的操作方式.

First off, you have to decide if you want your three ajax calls to be processed in parallel (running all at the same time, with less overall running time) or in sequence where one ajax calls runs, completes and then you launch the next ajax call. This is a key design decision that impacts how you do this.

使用$.when()时,将同时启动所有三个ajax调用.如果仅在所有结果都完成后才检查结果,则仍然可以按特定顺序处理结果(因为只有在所有结果可用时,才可以处理结果,并且将按请求的顺序来处理结果).但是,以这种方式进行操作时,所有ajax调用都将立即被立即发送.这样可以为您提供更好的端到端时间,因此,如果这对请求类型可行,那么通常这是一种更好的方法.

When you use $.when() you are launching all three ajax calls in parallel. If you examine the results only when all have completed, you can still process the results in a specific order (since you will be processing them only when all results are available and they will be available in the order requested). But, when doing it this way all the ajax calls will be initially sent at once. This will give you a better end-to-end time so if this is feasible for the types of requests, this is generally a better way to do it.

要做到这一点,您可以将所需的内容重组为类似这样的内容:

To do that, you can restructure what you have to something like this:

并行运行

var files = [
   'url1', 'url2', 'url3'
];

$.when($.ajax(files[0]),$.ajax(files[1]),$.ajax(files[2])).done(function(a1, a2, a3) {
   var results = [];
   results.push(a1[0]);
   results.push(a2[0]);
   results.push(a3[0]);
   console.log("got all results")
});

因为您要等到$.when().done()处理程序被调用,所有ajax结果才能立即准备好,并按请求的顺序由$.when()呈现(无论实际上是哪一个)首先完成),这样您就可以尽快获得结果,并以可预测的顺序显示它们.

Because you're waiting until the .done() handler for $.when() has been called, all the ajax results are ready at once and they are presented by $.when() in the order they were requested (regardless of which one actually finished first), so you get the results as quick as possible and they are presented in a predictable order.

请注意,我还将results数组的定义移到了$.when() done处理程序中,因为这是您知道数据实际有效的唯一位置(出于时序原因).

Note, I also moved the definition of the results array into the $.when() done handler because that's the only place you know the data is actually valid (for timing reasons).

并行运行-迭代任意长度数组

如果数组较长,可能会发现最好使用.map()之类的方法遍历数组,以循环方式处理它们,而不是单独列出它们:

If you had a longer array, you might find it better to iterate through your array with something like .map() to process them all in a loop rather than listing them individually:

var files = [
   'url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7'
];

$.when.apply($, files.map(function(url) {
    return $.ajax(url);
})).done(function() {
    var results = [];
    // there will be one argument passed to this callback for each ajax call
    // each argument is of this form [data, statusText, jqXHR]
    for (var i = 0; i < arguments.length; i++) {
        results.push(arguments[i][0]);
    }
    // all data is now in the results array in order
});


对Ajax调用进行排序

另一方面,如果您实际上要对ajax调用进行排序,以使第二个ajax调用直到第一个完成之前才开始(如果第二个ajax调用需要来自第一个ajax调用的结果,则可能需要执行某些操作)为了知道要请求或执行的操作),那么您需要一个完全不同的设计模式,而$.when()根本不是可行的方法(它仅执行并行请求).在这种情况下,您可能只想将结果与x.then().then()链接起来,然后可以按照您要求的顺序输出日志语句.

If, on the other hand, you actually want to sequence your ajax calls so the 2nd one doesn't start until the first one finishes (something that may be required if the 2nd ajax call needs results from the 1st ajax call in order to know what to request or do), then you need a completely different design pattern and $.when() is not the way to go at all (it only does parallel requests). In that case, you probably just want to chain your results with x.then().then() and you can then output the log statements in the sequence you asked for like this.

  $.ajax(files[0]).then(function(data0) {
      console.log("step 1.0");
      return $.ajax(files[1]);
  }).then(function(data1) {
      console.log("step 1.1");
      return $.ajax(files[2]);
  }).done(function(data2) {
      console.log("step 1.2");
      // all the ajax calls are done here
      console.log("step 2");
  });

控制台输出:

step 1.0
step 1.1
step 1.2
step 2

如果文件数组较长,也可以将该结构放入循环中,以自动运行N次连续Ajax调用.尽管您可以在进入results数组时收集结果,但通常顺序执行操作的原因是先前的结果被下一个ajax调用占用了,因此您通常只需要最终结果.如果您想随时收集结果,则可以在每一步将它们推入results数组中.

This structure can also be put into a loop to automatically run it for N sequential ajax calls if your array of files is longer. While you could collect the results as you go into the results array, often the reason things are done sequentially is that the prior results are consumed by the next ajax call so you often only need the final result. If you wanted to collect the results as you go, you could certainly push them into the results array at each step.

请注意,此处所承诺的优势在于,您可以在保持相同的顶层嵌套的同时对操作进行排序,而不必嵌套得越来越远.

Notice, the advantages that promises offer here in that you can sequence operations while staying at the same top level of nesting and not getting further and further nested.

对Ajax调用进行排序-迭代任意长度数组

这是循环中的排序顺序:

Here's what the sequencing would look like in a loop:

var files = [
   'url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7'
];

var results = [];
files.reduce(function(prev, cur, index) {
    return prev.then(function(data) {
        return $.ajax(cur).then(function(data) {
            console.log("step 1." + index);
            results.push(data);
        });
    })
}, $().promise()).done(function() {
    // last ajax call done
    // all results are in the results array
    console.log("step 2.0");
});

控制台输出:

step 1.0
step 1.1
step 1.2
step 1.3
step 1.4
step 1.5
step 1.6
step 2

Array.prototype.reduce()方法在这里很容易工作,因为它在处理每个单独的数组元素时会累积一个值,这是在为每个数组元素添加.then()时需要执行的操作. .reduce()迭代以$().promise()为空/已解决的诺言开始(还有其他方法也可创建这样的诺言),这为我们提供了一些在已解决的情况下开始执行.then()的机会.

The Array.prototype.reduce() method works handily here because it accumulates a single value as you process each individual array element which is what you need to do as you add .then() for each array element. The .reduce() iteration is started with an empty/resolved promise with $().promise() (there are other ways to also create such a promise) which just gives us something to start doing .then() on that is already resolved.

这篇关于jQuery,带有URL数组的$ .ajax的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆