【问题标题】:How to implement sequntial iteration with asynchronous code如何用异步代码实现顺序迭代
【发布时间】:2010-07-14 13:25:04
【问题描述】:

我想实现将文件(使用 XMLHttpRequest level2)顺序上传到服务器。得到一堆带有文件的 DOM 元素(FileAPI - W3C 草案)。我想按顺序上传(一个接一个),但 XMLHttpRequest 异步工作。小代码示例:

$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 FormData

  xhr.open("POST", 'server_url', true) // last true means "use asynch rq"
  xhr.send(fd)
}

此代码的问题是,FOR 循环在文件的上传过程中独立迭代。于是开始了更多的并行上传:

  • 迭代开始,
    • xhr 已创建/填充,
    • 上传开始,
    • 新迭代

即使之前的上传未完成,此设计也会创建新的 xhr 对象。但我仍然想保持上传的异步范式(没有浏览器阻塞、进度事件等)。只是想不通,如何等待当前上传完成,然后开始新的上传周期。

有什么想法吗?

【问题讨论】:

    标签: javascript events asynchronous


    【解决方案1】:

    您可以创建一个堆栈递归地处理请求,同时重复使用相同的请求对象。

    我知道,它摇滚! :) 这是你的代码:

    // 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());
    
    })();
    

    【讨论】:

    • 我认为这将是解决方案。非常感谢你。
    【解决方案2】:

    对于这类事情,我有一个有用的 javascript 库: http://caolanmcmahon.com/async.html

    您可以轻松地重写此代码以使用 forEachSeries 或 mapSeries... 如下:

    async.forEachSeries(thumbnails, function(thumb, callback){
        var xhr = new XMLHttpRequest();
        xhr.upload.onload = function(ev){ callback(); };
        ...
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      • 2020-04-03
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      相关资源
      最近更新 更多