如何使所有AJAX调用都是连续的?

时间:2022-10-17 00:19:11

I use jQuery. And I don't want parallel AJAX calls on my application, each call must wait the previous before starting. How to implement it? There is any helper?

我使用jQuery。我不希望在我的应用程序上进行并行AJAX调用,每次调用都必须在开始之前等待。如何实现它呢?有任何帮助吗?

UPDATE If there is any synchronous version of the XMLHttpRequest or jQuery.post I would like to know. But sequential != synchronous, and I would like an asynchronous and sequential solution.

如果存在XMLHttpRequest或jQuery的同步版本,则进行更新。我想知道。但是顺序!=同步的,我想要一个异步和顺序的解决方案。

11 个解决方案

#1


16  

There's a much better way to do this than using synchronous ajax calls. Jquery ajax returns a deferred so you can just use pipe chaining to make sure that each ajax call finishes before the next runs. Here's a working example with a more in depth example you can play with on jsfiddle.

有比使用同步ajax调用更好的方法。Jquery ajax返回一个延迟,因此您可以使用管道链接来确保每个ajax调用在下一次运行之前完成。这里有一个工作示例,其中有一个更深入的示例,您可以在jsfiddle。

// How to force async functions to execute sequentially 
// by using deferred pipe chaining.

// The master deferred.
var dfd = $.Deferred(),  // Master deferred
    dfdNext = dfd; // Next deferred in the chain
    x = 0, // Loop index
    values = [], 

    // Simulates $.ajax, but with predictable behaviour.
    // You only need to understand that higher 'value' param 
    // will finish earlier.
    simulateAjax = function (value) {
        var dfdAjax = $.Deferred();

        setTimeout(
            function () {
                dfdAjax.resolve(value);
            },
            1000 - (value * 100)
        );

        return dfdAjax.promise();
    },

    // This would be a user function that makes an ajax request.
    // In normal code you'd be using $.ajax instead of simulateAjax.
    requestAjax = function (value) {
        return simulateAjax(value);
    };

// Start the pipe chain.  You should be able to do 
// this anywhere in the program, even
// at the end,and it should still give the same results.
dfd.resolve();

// Deferred pipe chaining.
// What you want to note here is that an new 
// ajax call will not start until the previous
// ajax call is completely finished.
for (x = 1; x <= 4; x++) {

    values.push(x);

    dfdNext = dfdNext.pipe(function () {
        var value = values.shift();
        return requestAjax(value).
            done(function(response) {
                // Process the response here.

            });

    });

}

Some people have commented they have no clue what the code does. In order to understand it, you first need to understand javascript promises. I am pretty sure promises are soon to be a native javascript language feature, so that should give you a good incentive to learn.

一些人评论说他们不知道代码是做什么的。为了理解它,您首先需要理解javascript承诺。我确信,承诺很快就会成为一种本地javascript语言特性,因此这应该会给您提供良好的学习动机。

#2


6  

You have two choices that I can think of. One is to chain them through callbacks. The other is to make the calls synchronous rather than async.

你有两个选择,我能想到。一种是通过回调将它们链接起来。另一种方法是使调用同步,而不是异步。

Is there a reason you want them sequential? That will slow things down.

你想要它们是连续的吗?这会使事情变慢。

To make the call synchronous, you'll set the async option in the Ajax call to false. See the documentation at http://docs.jquery.com/Ajax/jQuery.ajax#options (click options tab to see them).

要使调用保持同步,将Ajax调用中的async选项设置为false。请参阅http://docs.jquery.com/Ajax/jQuery.ajax#options(单击options选项卡查看它们)中的文档。

#3


3  

Set the async option to false, e.g.,

将async选项设置为false,例如,

$.ajax({ async: false /*, your_other_ajax_options_here */ });

Reference: Ajax/jQuery.ajax

参考:Ajax / jQuery.ajax

#4


2  

You could give narrative javascript a try http://www.neilmix.com/narrativejs/doc/

您可以尝试一下叙述性javascript http://www.neilmix.com/narrativejs/doc/

I've never used it myself though. If I wanted to do this, I would setup some kind of abstraction for chaining asynchronous actions. As others have said, the synchonous version of the ajax object blocks events from being processed while it's waiting for a response. This causes the browser to look like it's frozen until it recieves a response.

不过我从来没用过。如果我想这样做,我将设置某种抽象来链接异步操作。正如其他人所说,ajax对象的同步版本在等待响应时阻止事件被处理。这使得浏览器看起来像是被冻结了,直到它收到响应。

#5


1  

The best way you could do this is by chaining callbacks as Nosredna said. I wouldn't recommend using synchronous XMLHttpRequest as they lock your entire application.

最好的方法是像Nosredna说的那样,链接回调。我不会推荐使用同步XMLHttpRequest,因为它们会锁定您的整个应用程序。

There aren't much helper for this as far as I know, but you could do something resembling a callback FIFO.

据我所知,这并没有多少帮助,但是你可以做一些类似于回调FIFO的事情。

#6


1  

Look at this: http://docs.jquery.com/Ajax/jQuery.ajax (click on the "options" tab).

看看这个:http://docs.jquery.com/Ajax/jQuery.ajax(单击“选项”选项卡)。

But remember a synchronous call will freeze the page until the response is received, so it can't be used in a production site, because users will get mad if for any reason they have to wait 30 seconds with their browser frozen.

但是请记住,同步调用将冻结页面,直到收到响应,因此不能在生产站点中使用它,因为如果用户不得不等待30秒,而浏览器却被冻结,那么他们会很生气。

EDIT: ok, with your update it's clearer what you want to achieve ;)

编辑:好的,随着你的更新,你想要达到的目标就更清晰了。

So, your code may look like this:

你的代码可能是这样的:

    $.getJSON("http://example.com/jsoncall", function(data) {
        process(data);
        $.getJSON("http://example.com/jsoncall2", function (data) {
            processAgain(data);
            $.getJSON("http://example.com/anotherjsoncall", function(data) {
                processAgainAndAgain(data);
            });
        });
    });

This way, the second call will only be issued when the response to the first call has been received and processed, and the third call will only be issued when the response to the second call has been received and processed. This code is for getJSON but it can be adapted to $.ajax.

这样,第二个调用将只在接收并处理第一个调用的响应时发出,而第三个调用将只在接收并处理第二个调用的响应时发出。这段代码是为getJSON编写的,但是可以将其修改为$.ajax。

#7


1  

And seems now you have a solution for this:

现在你似乎有了解决办法

http://api.jquery.com/category/deferred-object/

http://api.jquery.com/category/deferred-object/

or

http://www.slideshare.net/furf/making-ajax-sexy-jsconf-2010?from=ss_embed

http://www.slideshare.net/furf/making ajax jsconf - 2010 ?from=ss_embed——性感

#8


0  

Synchronous calls aren't necessarily slower, if you have an app where AJAX calls open, posts to, then closes a socket, multiple calls to the socket don't make sense as some sockets can only handle a single connection, in which case, queuing data so its only sent when the previous AJAX call has completed means much higher data throughput.

同步调用不一定慢,如果你有一个AJAX调用的应用程序打开,帖子,然后关闭套接字,多个调用一些插座的插座没有意义只能处理一个连接,在这种情况下,排队时数据只所以它发送之前的AJAX调用完成意味着更高的数据吞吐量。

#9


0  

(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. requests 3 json files with jQuery ajax calls
  2. 使用jQuery ajax调用请求3个json文件。
  3. process in sequence (not in parallel) with await
  4. 按顺序(而不是并行)处理等待
  5. works in Chrome/Firefox/Edge (as of 1/30/2018)
  6. 工作在Chrome/Firefox/Edge (1/30/2018)

more at MDN

在中数

#10


-1  

How about using Node.js events?

如何使用节点。js事件吗?

var EventEmitter = require('events').EventEmitter;
var eventEmitter = new EventEmitter();
var $ = require('jquery');

var doSomething = function (responseData) {
  var nextRequestData = {};
  // do something with responseData
  return nextRequestData;
};

// ajax requests
var request1 = $.ajax;
var request2 = $.ajax;
var requests = [request1, request2];

eventEmitter.on('next', function (i, requestData) {
  requests[i](requestData).then(
    function (responseData) {
      console.log(i, 'request completed');
      if (i+1 < requests.length) {
        var nextRequestData = doSomething(responseData);
        eventEmitter.emit('next', i+1, nextRequestData);
      }
      else {
        console.log('completed all requests');
      }
    },
    function () {
      console.log(i, 'request failed');
    }
  );
});

var data = {
  //data to send with request 1
};
eventEmitter.emit('next', 0, data);

#11


-1  

sequential != synchronous, and I would like an asynchronous and sequential solution

顺序!=同步,我想要一个异步和顺序的解决方案

Synchronous execution generally means "using the same clock", while sequential execution means "following in order or sequence".

同步执行通常意味着“使用相同的时钟”,而顺序执行则意味着“按照顺序或顺序执行”。

For your specific use case I think both conditions must be met, as asynchronous execution implies the possibility of a non-sequential result.

对于您的特定用例,我认为必须满足这两个条件,因为异步执行意味着出现非连续结果的可能性。

#1


16  

There's a much better way to do this than using synchronous ajax calls. Jquery ajax returns a deferred so you can just use pipe chaining to make sure that each ajax call finishes before the next runs. Here's a working example with a more in depth example you can play with on jsfiddle.

有比使用同步ajax调用更好的方法。Jquery ajax返回一个延迟,因此您可以使用管道链接来确保每个ajax调用在下一次运行之前完成。这里有一个工作示例,其中有一个更深入的示例,您可以在jsfiddle。

// How to force async functions to execute sequentially 
// by using deferred pipe chaining.

// The master deferred.
var dfd = $.Deferred(),  // Master deferred
    dfdNext = dfd; // Next deferred in the chain
    x = 0, // Loop index
    values = [], 

    // Simulates $.ajax, but with predictable behaviour.
    // You only need to understand that higher 'value' param 
    // will finish earlier.
    simulateAjax = function (value) {
        var dfdAjax = $.Deferred();

        setTimeout(
            function () {
                dfdAjax.resolve(value);
            },
            1000 - (value * 100)
        );

        return dfdAjax.promise();
    },

    // This would be a user function that makes an ajax request.
    // In normal code you'd be using $.ajax instead of simulateAjax.
    requestAjax = function (value) {
        return simulateAjax(value);
    };

// Start the pipe chain.  You should be able to do 
// this anywhere in the program, even
// at the end,and it should still give the same results.
dfd.resolve();

// Deferred pipe chaining.
// What you want to note here is that an new 
// ajax call will not start until the previous
// ajax call is completely finished.
for (x = 1; x <= 4; x++) {

    values.push(x);

    dfdNext = dfdNext.pipe(function () {
        var value = values.shift();
        return requestAjax(value).
            done(function(response) {
                // Process the response here.

            });

    });

}

Some people have commented they have no clue what the code does. In order to understand it, you first need to understand javascript promises. I am pretty sure promises are soon to be a native javascript language feature, so that should give you a good incentive to learn.

一些人评论说他们不知道代码是做什么的。为了理解它,您首先需要理解javascript承诺。我确信,承诺很快就会成为一种本地javascript语言特性,因此这应该会给您提供良好的学习动机。

#2


6  

You have two choices that I can think of. One is to chain them through callbacks. The other is to make the calls synchronous rather than async.

你有两个选择,我能想到。一种是通过回调将它们链接起来。另一种方法是使调用同步,而不是异步。

Is there a reason you want them sequential? That will slow things down.

你想要它们是连续的吗?这会使事情变慢。

To make the call synchronous, you'll set the async option in the Ajax call to false. See the documentation at http://docs.jquery.com/Ajax/jQuery.ajax#options (click options tab to see them).

要使调用保持同步,将Ajax调用中的async选项设置为false。请参阅http://docs.jquery.com/Ajax/jQuery.ajax#options(单击options选项卡查看它们)中的文档。

#3


3  

Set the async option to false, e.g.,

将async选项设置为false,例如,

$.ajax({ async: false /*, your_other_ajax_options_here */ });

Reference: Ajax/jQuery.ajax

参考:Ajax / jQuery.ajax

#4


2  

You could give narrative javascript a try http://www.neilmix.com/narrativejs/doc/

您可以尝试一下叙述性javascript http://www.neilmix.com/narrativejs/doc/

I've never used it myself though. If I wanted to do this, I would setup some kind of abstraction for chaining asynchronous actions. As others have said, the synchonous version of the ajax object blocks events from being processed while it's waiting for a response. This causes the browser to look like it's frozen until it recieves a response.

不过我从来没用过。如果我想这样做,我将设置某种抽象来链接异步操作。正如其他人所说,ajax对象的同步版本在等待响应时阻止事件被处理。这使得浏览器看起来像是被冻结了,直到它收到响应。

#5


1  

The best way you could do this is by chaining callbacks as Nosredna said. I wouldn't recommend using synchronous XMLHttpRequest as they lock your entire application.

最好的方法是像Nosredna说的那样,链接回调。我不会推荐使用同步XMLHttpRequest,因为它们会锁定您的整个应用程序。

There aren't much helper for this as far as I know, but you could do something resembling a callback FIFO.

据我所知,这并没有多少帮助,但是你可以做一些类似于回调FIFO的事情。

#6


1  

Look at this: http://docs.jquery.com/Ajax/jQuery.ajax (click on the "options" tab).

看看这个:http://docs.jquery.com/Ajax/jQuery.ajax(单击“选项”选项卡)。

But remember a synchronous call will freeze the page until the response is received, so it can't be used in a production site, because users will get mad if for any reason they have to wait 30 seconds with their browser frozen.

但是请记住,同步调用将冻结页面,直到收到响应,因此不能在生产站点中使用它,因为如果用户不得不等待30秒,而浏览器却被冻结,那么他们会很生气。

EDIT: ok, with your update it's clearer what you want to achieve ;)

编辑:好的,随着你的更新,你想要达到的目标就更清晰了。

So, your code may look like this:

你的代码可能是这样的:

    $.getJSON("http://example.com/jsoncall", function(data) {
        process(data);
        $.getJSON("http://example.com/jsoncall2", function (data) {
            processAgain(data);
            $.getJSON("http://example.com/anotherjsoncall", function(data) {
                processAgainAndAgain(data);
            });
        });
    });

This way, the second call will only be issued when the response to the first call has been received and processed, and the third call will only be issued when the response to the second call has been received and processed. This code is for getJSON but it can be adapted to $.ajax.

这样,第二个调用将只在接收并处理第一个调用的响应时发出,而第三个调用将只在接收并处理第二个调用的响应时发出。这段代码是为getJSON编写的,但是可以将其修改为$.ajax。

#7


1  

And seems now you have a solution for this:

现在你似乎有了解决办法

http://api.jquery.com/category/deferred-object/

http://api.jquery.com/category/deferred-object/

or

http://www.slideshare.net/furf/making-ajax-sexy-jsconf-2010?from=ss_embed

http://www.slideshare.net/furf/making ajax jsconf - 2010 ?from=ss_embed——性感

#8


0  

Synchronous calls aren't necessarily slower, if you have an app where AJAX calls open, posts to, then closes a socket, multiple calls to the socket don't make sense as some sockets can only handle a single connection, in which case, queuing data so its only sent when the previous AJAX call has completed means much higher data throughput.

同步调用不一定慢,如果你有一个AJAX调用的应用程序打开,帖子,然后关闭套接字,多个调用一些插座的插座没有意义只能处理一个连接,在这种情况下,排队时数据只所以它发送之前的AJAX调用完成意味着更高的数据吞吐量。

#9


0  

(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. requests 3 json files with jQuery ajax calls
  2. 使用jQuery ajax调用请求3个json文件。
  3. process in sequence (not in parallel) with await
  4. 按顺序(而不是并行)处理等待
  5. works in Chrome/Firefox/Edge (as of 1/30/2018)
  6. 工作在Chrome/Firefox/Edge (1/30/2018)

more at MDN

在中数

#10


-1  

How about using Node.js events?

如何使用节点。js事件吗?

var EventEmitter = require('events').EventEmitter;
var eventEmitter = new EventEmitter();
var $ = require('jquery');

var doSomething = function (responseData) {
  var nextRequestData = {};
  // do something with responseData
  return nextRequestData;
};

// ajax requests
var request1 = $.ajax;
var request2 = $.ajax;
var requests = [request1, request2];

eventEmitter.on('next', function (i, requestData) {
  requests[i](requestData).then(
    function (responseData) {
      console.log(i, 'request completed');
      if (i+1 < requests.length) {
        var nextRequestData = doSomething(responseData);
        eventEmitter.emit('next', i+1, nextRequestData);
      }
      else {
        console.log('completed all requests');
      }
    },
    function () {
      console.log(i, 'request failed');
    }
  );
});

var data = {
  //data to send with request 1
};
eventEmitter.emit('next', 0, data);

#11


-1  

sequential != synchronous, and I would like an asynchronous and sequential solution

顺序!=同步,我想要一个异步和顺序的解决方案

Synchronous execution generally means "using the same clock", while sequential execution means "following in order or sequence".

同步执行通常意味着“使用相同的时钟”,而顺序执行则意味着“按照顺序或顺序执行”。

For your specific use case I think both conditions must be met, as asynchronous execution implies the possibility of a non-sequential result.

对于您的特定用例,我认为必须满足这两个条件,因为异步执行意味着出现非连续结果的可能性。