Reputation: 2472
I am trying to call service which returns one row of information at a time. I will fetch 100 such rows. I want a particular time gap between each hit to the service. It does not have to be exact, but at least 200 ms. I had been using jquery for the calls. Something like:
for 1 to 100
window.setTimeout(function(rowNumber){
$.ajax({
url:
datatype: 'json'
async:false
success: function to display row
});
}, 10000, someParam);
Also, I have this call inside a xmlhttp.onreadystatechange
function.
What happens is that I get a 10 second delay in the beginning, but then all the rows appear in an avalanche. I need a delay between each call.
Thanks!
Upvotes: 1
Views: 1340
Reputation: 4679
First, you need think about create a bulk action in the server for replay all info in a single shot.
The other important concept, avoid the sync connections. In your case 100 connection will block the browser during the process.
All elements is write in the same moment for use sync, the browser is block for write any element in the dom.
https://jsfiddle.net/luarmr/3a81nn9z/
the first: Remember that the browser has a call limitations, it is true that the user can change it in this configuration, maybe it is not your solution, but introduce concept to the second and third solution, in this case we ask for all request in the same moment.
HTML
<ul id="result"></ul>
JS
function insertPosition(pos, text){
var element = $("#result > li:nth-child(" + (pos+1) + ")"),
html = '<li>' + text + '</li>';
if (element.length === 0) {
$("#result").append(html);
} else {
element.before(html);
}
}
$(document).ready(function() {
for(var i = 0; i < numberRequest; i++) {
$.ajax({
url: '/echo/html/',
type: 'POST',
data: 'html=' + i,
cache: false,
success: insertPosition.bind(this, i)
});
}
});
Basically, you call the ajax inside the loop, and you need be sure to add the new element in the correct place. insertPosition test if you already have an element in that position, if you have one the function insert the element before it. If you don't have, they insert the element in the last position. The other important here is the function bind, you can see more here. No wait, when I have the element I add it in the list.
The second (same html):
var callbackFunction = function(num, max, returnhtml){
num++;
$("#result2").append('<li>' + returnhtml + '</li>');
if (num<max) {
callAjax(num,max);
}
};
function callAjax(num,max){
$.ajax({
url: '/echo/html/',
type: 'POST',
data: 'html=' + num,
cache: false,
success: callbackFunction.bind(this, num, max)
});
}
$(document).ready(function() {
callAjax(0,numberRequest);
});
The difference here is the number of concurrent connections. In this case, we wait for the response and then we send the next request. We can always insert in the end.
Third way:
var callbackFunction2 = function (num, max, returnhtml) {
num++;
$("#result3").append('<li>' + returnhtml + '</li>');
if (num < max) {
setTimeout(window.callAjax2.bind(window, num, max), 500);
}
};
function callAjax2(num, max) {
$.ajax({
url: '/echo/html/',
type: 'POST',
data: 'html=' + num,
cache: false,
success: callbackFunction2.bind(this, num, max)
});
}
$(document).ready(function () {
callAjax2(0, numberRequest);
});
This is only an update of second version, with a timeout. Actually I prefer the second one for your case.
Upvotes: 1
Reputation: 24541
Just use the loop variable as a multiplier for your time to achieve that:
for (var i=0;i<100;i++) {
window.setTimeout(function(){
$.ajax({
url:
datatype: 'json'
async: false
success: function to display row
});
}, i * 200);
}
Upvotes: 0