0

I believe I am timing out a web service by making too many calls in a short period of time. I am wanting to wait about 5 seconds between each iteration of a $.each loop in my jquery.

Here is a look at what I have:

function submitMyList(myList) { $.each(JSON.parse(myList), function (key, value) { setTimeout( function(){ $.ajax({ type: 'POST', url: '@Url.Action("submitMyList", "myController")', dataType: 'html', contentType: 'application/json; charset=utf-8', data: JSON.stringify(//passing my values), success: function (result) { //success code }, error: function (result) { //error code }, complete: function () { //completion code } }); }, 5000) }); } 

This still is execution extremely quick, one after another.

2
  • Instead of trying to make the same request every five seconds, wait until the previous request has finished before making the next one. Commented Feb 24, 2015 at 15:03
  • @zzzzBov I am not really wanting to perform this like that. Each request can take about 1-2 minutes to complete. My list could potentially be as high long as about 70 entries. So performing the submission could take a long time that way. Commented Feb 24, 2015 at 15:16

2 Answers 2

3

What's happening is that when you run your "each", you set a lot of timers immediately, which all wait 5 seconds and then run at the same time. This is due to the fact that the each just wants to finish it's loop as quickly as possible, and it runs all of it's functions (including the "setTimeout" function). It doesn't have to wait for anything, so runs of and sets a whole lotta' timeouts :)

Easiest solution would be to let the setTimeout wait 5000 * num milliseconds and increase the num with every loop, something like this:

function submitMyList(myList) { var num = 0; $.each(JSON.parse(myList), function (key, value) { num++; setTimeout( function(){ $.ajax({ type: 'POST', url: '@Url.Action("submitMyList", "myController")', dataType: 'html', contentType: 'application/json; charset=utf-8', data: JSON.stringify(//passing my values), success: function (result) { //success code }, error: function (result) { //error code }, complete: function () { //completion code } }); }, 5000*num); }); } 
Sign up to request clarification or add additional context in comments.

3 Comments

It should work, look at this minimal test in JSFiddle: jsfiddle.net/cy0uqLnj To add to my answer, what would be even better is to use the "success" to set a new timer, advantage is you don't have the risk to "heap up" calls if there's a delay in the calls. Disadvantage is everything stops if a request fails.
I apologize this does work, I got myself a little turned around. I am still a little confused as to why it works. The working in the first phrase is a little confusing to me.
No problem, happy it works. Have clarified my answer a bit, hope it helps.
2

An approach of this kind could work:

$(document).ready(function () { var a = new Array("Apples", "Bananas", "Oranges") jQuery.each(a, function (idx, val) { setTimeout(function() { console.log("At "+idx+" Val "+val) }, idx * 5000); }) }) 

in your specific case try this:

function submitMyList(myList) { var idx = 0; $.each(JSON.parse(myList), function (key, value) { setTimeout( function(){ $.ajax({ type: 'POST', url: '@Url.Action("submitMyList", "myController")', dataType: 'html', contentType: 'application/json; charset=utf-8', data: JSON.stringify(//passing my values), success: function (result) { //success code }, error: function (result) { //error code }, complete: function () { //completion code } }); }, idx*5000) idx++; }); }; 

example here: http://jsfiddle.net/1w6uxLxs/1/

The idea You have to multiply your timeout by the number of iterations because what is happening is that the timeouts are set one after another (basically simultaneously), because what happens is that the loop goes through all elements and for each element you instruct the browser (setTimeout) to execute a function after a certain amount of time. By multiplying this amount of time by the index you get the "delay" effect. Have a look at what happens in the console in this example: http://jsfiddle.net/1w6uxLxs/2/

2 Comments

Thanks for your help, this does work like a charm. Would you mind explaining why I am having to multiply by idx every time the loop iterates?
I updated the answer trying to explain the idea. Let me know if it's clear.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.