开发者

send $.post() one at a time ("adding a pause" but really: toggling a 'transmit' flag)

开发者 https://www.devze.com 2023-03-26 21:35 出处:网络
in jQuery, I iterate over an xml list of areas and do a POST request to get detailed information about each area.Because sending thousands of requests at once is debilitating for the client and server

in jQuery, I iterate over an xml list of areas and do a POST request to get detailed information about each area. Because sending thousands of requests at once is debilitating for the client and server, I would like to set a flag so that I wait for a request to finish before sending the subsequent [next] request.

if the xml looks like this:

<area>5717</area>
<area>5287</area>
<area>5376</area>

then the xml parsing kinda looks like:

$(xml).find("area").each( function() {
  doPost();
}

and the doPost() function looks like

doPost : function () {
    $.post( ... )
}

Basically, I would like to add a toggling "wait" but I'm not sure how to achieve this. Is there a way I can keep the essential ".each" iteration or is开发者_开发百科 another type of loop better for this?

Thanks in advance.


A general algorithm off the top of my head: You could put the whole list into an array. Take the first item of the array and post it. In the success handler of your post you could recursively call the function with the next index int the list.

I wouldn't use async: false because it would then be a blocking operation, which I assume the OP doesn't want.


You can use:

$.ajaxSetup({async:false});

at the top of your script to make your AJAX calls synchronous.

Alternately, you can replace $.post() with $.ajax() and set the async flag to false.


can you do a setTimeout ? that will allow for the function to still process asynchronous and allow for you to wait for some time in there too.

http://www.w3schools.com/js/js_timing.asp

setTimeout(function() {}, 5000)


You can refactor your doPost() function to take the <area> element to process as an argument, and chain into the next element from your success callback. Something like:

(function doPost($area) {
    if ($area.length > 0) {
        $.post({
            // your options,
            success: function() {
                // your success handling...
                doPost($area.next("area"));
            }
        });
    }
})($(xml).find("area").first());

EDIT: Maybe the code above was a little too compact indeed.

Basically, the aim is to refactor your function so that it takes a jQuery object containing the next <area> element to process, or nothing if processing should stop:

function doPost($area) {
    if ($area.length > 0) {
        // Perform POST request and call ourselves from success callback
        // with next <area> element (or nothing if there's no such element).
    }
}

Then call this function with the first <area> element to process:

doPost($(xml).find("area").first());

The first code fragment in my answer does both at the same time. Functions are first-class objects in Javascript, and you can call a function you've just defined by enclosing its definition with parenthesis and providing the usual argument list, also surrounded by parenthesis.

0

精彩评论

暂无评论...
验证码 换一张
取 消