0

I have a loop which sends AJAX requests and it works well with 5 files or so, but when I try to upload more than 5 files. The browser stops.

Is there any way to create or define a maximum number of simultaneous connections and after they finish, starting the other?.

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

var http = new XMLHttpRequest();
var data = "type=ZIP&file=" + base_64_encode(files[i]);

http.open("POST", "update.php");
http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
http.send(data);

}
tshepang
  • 12,111
  • 21
  • 91
  • 136
Sergio
  • 1,013
  • 8
  • 8
  • Each browser has an internal limit of how many concurrent connections it will make, both in total and to each domain separately. You cannot affect that. – Jon Jan 19 '14 at 22:55
  • Not a simple way, no. However, there are specialised libraries to deal with such problems, e.g. https://github.com/caolan/async#parallellimittasks-limit-callback – Bergi Jan 19 '14 at 22:56

1 Answers1

0

If I understand right, you just want to throttle them? You can do this by keeping track of how many are concurrent, maintaining a queue of requests in excess of the max concurrency, and attaching a callback to your requests that updates the current concurrency value and triggers that next queued function if applicable:

function throttleFileUploads(files, maxConcurrent) {
  var queue = [];
  var currentlyActive = 0;

  function moreAllowed() { return (currentlyActive < maxConcurrent); }

  function uploadFile(file, callback) {
    currentlyActive += 1;
    var http = new XMLHttpRequest();
    var data = "type=ZIP&file=" + base_64_encode(file);

    http.open("POST", "update.php");
    http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    http.onreadystatechange = function() {
      if (http.readyState == 4) { callback(); }
    };

    http.send(data);
  }

  function finished() {
    currentlyActive -= 1;
    if (moreAllowed() && queue.length) { queue.pop()(); }
  }

  files.forEach(function(file) {
    var action = uploadFile.bind(null, file, finished);
    if (moreAllowed()) {
      action();
    } else {
      queue.push(action);
    }
  });
}

(Note -- I didn't test it, but I think the idea is sound.)

throttleFileUploads(files, 5);
Semicolon
  • 6,793
  • 2
  • 30
  • 38
  • Thanks for your quick reply, but apparently it did not work, not their code of course. Apparently the files I'm using are very heavy (8 Mb). Have any other ideas I can use for this case? Any link that can guide me? The truth is that I'm starting to use JavaScript and really like it, but of course that is not enough. – Sergio Jan 20 '14 at 14:35
  • Can you give more details about what happens? Does the above code fail with an error or is it 'working' but the uploads continue to silently fail to occur? – Semicolon Jan 21 '14 at 05:04
  • I think the problem is when I convert the files to base64. I think I need to create a list of files to be converted in base64 for after sent, in the list save the name, size and type. Then, from that list, I have to convert them to base64 and send it one at a time (to avoid saturating the browser) and delete them from that list once sent (to make room for next file). I tried to implement your code but when converting to base64 and send it always load the file with less Mb first and after the heavier (not in order of arrival). After passing the usual (the browser stopped). – Sergio Jan 21 '14 at 15:07
  • Any idea how to do it? I read something about emulate threads in JavaScript with setInterval and clearInterval, but I can not find the solution. – Sergio Jan 21 '14 at 15:15
  • Something tells me I'm near, but I do not know. – Sergio Jan 21 '14 at 15:16
  • Yes, it sounds like the problem you face now is most likely related to how you are attempting to upload the file. It did look funny to me, but I've never had to upload a large amount of data with xhr. This question/answer may be relevant: http://stackoverflow.com/questions/10475313/ajax-file-upload-with-xmlhttprequest#answer-11771857 – Semicolon Jan 21 '14 at 19:00