I want to implement sequential upload of files (with XMLHttpRequest level2) to server. Got bunch of DOM elements with File attached (FileAPI - W3C draft). I want to upload in sequence (one after another), but XMLHttpRequest works asynchronously. Little code sample:
$thumbnails = $('queue').find('.item');
for (var i = 0, len = thumbnails.length; i < len; i++) {
var xhr = new XMLHttpRequest();
xhr.upload.onload = function(ev){}; // fires on upload complete
var fd = new FormData
fd.append('Files['+i+']', $thumbnails[i].file) // insert atached File to F开发者_C百科ormData
xhr.open("POST", 'server_url', true) // last true means "use asynch rq"
xhr.send(fd)
}
Problem with this code is, that FOR cycle iterates independently on upload proces of file. So more paralel uploads are started:
- iteration starts,
- xhr is created/populated,
- upload begins,
- new iteration
This design create new xhr object even if previous upload is not finished. But I still want to hold asynch paradigm (no browser block, progress events, etc.) of upload. Just cannot figure out, how to wait for current upload to finish and then start new upload cycle.
Any ideas?
You can create a stack and handle the requests recursively, also reusing the same request object.
I know, it rocks! :) Here is your code:
// last in, first out.
var stack = [];
$('queue').find('.item').each(function(i, el){
// insert atached File to FormData
var fd = new FormData();
fd.append('Files['+i+']', el.file);
stack.push(fd);
});
var xhr = new XMLHttpRequest();
(function recur() {
// fires on upload complete
xhr.upload.onload = function(ev) {
// do recursion until the stack is not empty
if (stack.length) recur();
};
// send an asynchronous POST request
xhr.open("POST", 'server_url', true);
xhr.send(stack.shift());
})();
I have a useful javascript library for this sort of thing: http://caolanmcmahon.com/async.html
You could easily rewrite this code to use forEachSeries or mapSeries... along the lines of:
async.forEachSeries(thumbnails, function(thumb, callback){
var xhr = new XMLHttpRequest();
xhr.upload.onload = function(ev){ callback(); };
...
});
精彩评论