javascript 排队多个 AJAX 请求,等待响应而不冻结浏览器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17518461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 08:37:36  来源:igfitidea点击:

Queue multiple AJAX requests, waiting for response and not freezing browser?

javascriptjqueryajaxqueue

提问by

I am working a script, I need to loop an array of AJAX requests:

我正在编写一个脚本,我需要循环一组 AJAX 请求:

$('#fetchPosts').click(function(){ 

    for(var i=0; i < link_array.length; i++) {

        settings = {
           // some object not relevant
        }

        var status = main_ajaxCall(settings, i); // ajax call
     }
});

function main_ajaxCall(settings, i) {

   $.ajax({ 
     type: "POST",
     url: "../model/insert.php",
     data:{obj_settings: settings},
     dataType: "json",
     cache: false,
     success: function (data) {
         // some handeling here
         return 0;
     },
     error: function(XMLHttpRequest, textStatus, errorThrown) {
         return 1;
     },
};

Why does the AJAX requests fire instantly? It does not seem to wait for a response from model/insert.php, is there any way to force it to wait for a response before firing the next AJAX request?

为什么 AJAX 请求会立即触发?它似乎没有等待来自 model/insert.php 的响应,有没有办法强制它在触发下一个 AJAX 请求之前等待响应?

EDIT 1:

编辑 1:

It seems I wasnt clear, sorry, I dont want it to wait, I want to queue up the calls.

好像没说清楚,不好意思,不想等了,想排队接听电话。

I cant make the call in one request, this is impossible in my current situation.

我无法在一个请求中拨打电话,这在我目前的情况下是不可能的。

采纳答案by Samuel Liew

Set async to false if you want to wait for a response (default: true)

如果要等待响应,请将 async 设置为 false(默认值:true)

$.ajax({
    async: false,
    ...

http://api.jquery.com/jQuery.ajax/

http://api.jquery.com/jQuery.ajax/

If you do not want blocking, you can set a success handler function using .ajaxComplete(), and you have to keep track of active AJAX connections if you want to wait for all to complete - How to know when all ajax calls are complete

如果您不想阻塞,则可以使用 设置成功处理函数.ajaxComplete(),如果您想等待所有连接完成,则必须跟踪活动的 AJAX 连接 -如何知道所有 ajax 调用何时完成

The best solution would be to minimize the number of AJAX requests to one. If you have to make a loop of AJAX requests, the logic could be simplified somewhere (put that in the server perhaps?)

最好的解决方案是将 AJAX 请求的数量减少到一个。如果您必须进行 AJAX 请求循环,则可以在某处简化逻辑(也许将其放在服务器中?)

EDIT 1:(In response to OP edit)

编辑 1:(响应 OP 编辑​​)

If you want to queue the AJAX requests, this question has been answered before here:

如果您想对 AJAX 请求进行排队,这里之前已经回答了这个问题:

You could also use these libraries (all you needed to do was Google):

你也可以使用这些库(你需要做的就是谷歌):

回答by deadbeef404

It fires instantly and doesn't wait around because that's what AJAX does best (The first A stands for asynchronous).

它立即触发并且不会等待,因为这是 AJAX 最擅长的(第一个 A 代表异步)。

The request to a server could take a long time to respond, and in most cases, don't want user's browser's freezing up or stopping them from doing anything else. If you do, you could probably just use a normal request.

对服务器的请求可能需要很长时间才能响应,并且在大多数情况下,不希望用户的浏览器冻结或阻止他们执行任何其他操作。如果你这样做,你可能只使用一个普通的请求。

This is the reason you give it functions for success error, so it can call them when the server responds.

这就是您为成功错误提供函数的原因,因此它可以在服务器响应时调用它们。

If you want nothing to be able to happen in the browser while you're calling insert.php, you could drop an overlay (eg. dark div) over everything with a loading image and remove it on success.

如果您不希望在调用 insert.php 时浏览器中发生任何事情,您可以在带有加载图像的所有内容上放置一个覆盖层(例如深色 div),并在成功时将其删除。

Maybe replace the $('#fetchPosts') element with "loading..." text and then reverse it when done. Hiding visibility of the fetchPosts element and adding a different "loading.." element is a nice way.

也许用“正在加载...”文本替换 $('#fetchPosts') 元素,然后在完成后将其反转。隐藏 fetchPosts 元素的可见性并添加不同的“loading..”元素是一种不错的方法。

回答by deadbeef404

Your AJAX call willwait for a response from the server, but wil do so asynchronously. That is, your script will continue to execute rather than block the browser while the server responds. When the server responds (or when the request times out - usually several seconds) your success:or error:functions will then execute.

您的 AJAX 调用等待来自服务器的响应,但会异步执行。也就是说,您的脚本将继续执行,而不是在服务器响应时阻止浏览器。当服务器响应时(或当请求超时 - 通常是几秒钟)您的success:error:函数将执行。

The effect of your code here is to create several concurrent requests based on the link_array length.

此处代码的作用是根据 link_array 长度创建多个并发请求。

You could specify async:falsein your AJAX call, but this would freeze the browser while all the AJAX calls are made.

您可以async:false在 AJAX 调用中指定,但这会在进行所有 AJAX 调用时冻结浏览器。

You should rewrite your code to execute all the handling as part of your success:function. I'd recommend you rewrite your code to assemble all your request into one, and make one AJAX call rather than several, and have the server return all the responses as one block. I can't suggest exactly how you do that - it's implementation dependent.

您应该重写代码以将所有处理作为success:函数的一部分来执行。我建议您重写代码,将所有请求组合成一个,并进行一次 AJAX 调用而不是多次调用,并让服务器将所有响应作为一个块返回。我不能确切地建议您如何做到这一点 - 它取决于实现。

EDITED:In response to your clarification, if you want them to be called in order, you'll need the success function to call the next one. You'll then have a chain of success calls the next, whose success calls the next, whose success calls the next.. etc until the last one which does the final processing. One way would be to pass the call number to the success function.

编辑:为了回应您的澄清,如果您希望按顺序调用它们,您将需要成功函数来调用下一个。然后,您将有一连串成功调用下一个,成功调用下一个,成功调用下一个……等等,直到最后一个进行最终处理。一种方法是将调用号传递给成功函数。