基于WinJS Promise的文件上传队列

时间:2014-12-05 14:37:20

标签: javascript queue promise winjs blockingqueue

方案

我需要一个后台上传队列,将文件发送到服务器。 队列应按顺序发送文件,因为它们被推入队列(FIFO)。

我的解决方案

var pendingFiles = [];
var filesOperation = null;

uploadNextAsync = function(file) {
  var next;
  if (!pendingFiles.length) {
    return WinJS.Promise.as();
  }
  next = pendingFiles.shift();
  fileslogger.debug("Uploading " + next);
  return fileQuery.folder.getFileAsync(next).then(function(file) {
    return Server.sendFileAsync(file).then(function() {
      return filesOk += 1;
    }, function(error) {
      filesNok += 1;
      return logger.error(error.message, error);
    }).then(function() {
      if (pendingFiles.length) {
        return uploadNextAsync(inspection);
      }
    });
  });
};

createTaskForFile = function(file) {
  if (pendingFiles.length == 0) {
    pendingFiles = [file.name]
    filesOperation = uploadNextAsync(file);
  } else {
    pendingFiles.push(file.name);
    return filesOperation.then(function() {
      return uploadNextAsync(file);
    });
  }
};

问题

似乎有时如果连续快速调用createTaskForFile,那么最终会同时上传2个文件。那么在createTastForFile函数中它是如何使用fileOperation.then构造或者在uploadNextAsync中做错了什么的某个小故障呢?

1 个答案:

答案 0 :(得分:1)

您的问题是pendingFiles始终为空。在createTaskForFile中,您可以将其设置为单元素数组,但立即调用uploadNextAsync()将其移出。我想如果你在上传文件后移动文件,你的脚本可能会有用。

但是,实际上你不需要这个数组。您可以将操作排队到filesOperation,这将是表示上传所有当前文件的承诺。

var filesOperation = WinJS.Promise.as();
function createTaskForFile(file) {
  return filesOperation = filesOperation.then(function() {
    return uploadNextAsync(file);
  });
}

function uploadAsync(next) {
  fileslogger.debug("Uploading " + next.name);
  return fileQuery.folder.getFileAsync(next.name).then(function(file) {
    return Server.sendFileAsync(file);
  }).then(function() {
    return filesOk += 1;
  }, function(error) {
    filesNok += 1;
    return logger.error(error.message, error);
  });
}