Javascript Firefox UI在使用Addon SDK API下载许多文件时变得无响应

Javascript Firefox UI在使用Addon SDK API下载许多文件时变得无响应,javascript,firefox,firefox-addon,firefox-addon-sdk,Javascript,Firefox,Firefox Addon,Firefox Addon Sdk,我有一个很难调试的问题,我需要使用firefox插件sdk API在后台下载大量(~400)相当小(~3-4mb)的文件 我尝试使用旧API()和新API()(缩短代码): Task.spawn(函数(){ 对于(var i=0;i

我有一个很难调试的问题,我需要使用firefox插件sdk API在后台下载大量(~400)相当小(~3-4mb)的文件

我尝试使用旧API()和新API()(缩短代码):

Task.spawn(函数(){
对于(var i=0;i
但是UI在一段时间后变得非常无响应,我尝试使用同一个文件并覆盖它,因为我的第一个猜测是windows文件句柄随着时间的推移而累积,但没有帮助。它似乎与系统性能无关,有时也会工作,5分钟后在同一台机器上出现故障


使用firefox sdk api下载大量文件是否存在已知问题,或者我是否做错了什么?

我发现通过使用替代api,下载速度更快,ui响应更快:

function downloadFromUrl(url, file, callback) {
  var channel = chrome.Cc["@mozilla.org/network/io-service;1"]
               .getService(chrome.Ci.nsIIOService)
               .newChannel(url, 0, null);

  var bstream = chrome.Cc["@mozilla.org/binaryinputstream;1"]
                .createInstance(chrome.Ci.nsIBinaryInputStream);
  bstream.setInputStream(channel.open());

  var fos = chrome.Cc["@mozilla.org/network/safe-file-output-stream;1"]
               .createInstance(chrome.Ci.nsIFileOutputStream);
  try {
    fos.init(file, 0x04 | 0x08 | 0x10 | 0x20 | 0x40, 0600, 0); // see:https://developer.mozilla.org/en-US/docs/PR_Open#Parameters

    var length = 0;
    var size = 0;
    while(size = bstream.available()) {
      fos.write(bstream.readBytes(size), size);
      length += size;
      callback(length);
    }
  } finally {
    if (fos instanceof chrome.Ci.nsISafeOutputStream) {
      fos.finish();
    } else {
      fos.close();
    }
  }
}
我知道这是一种原始api,但它比其他api工作得更好

编辑:

我改进了上面的功能,但可能太臃肿了,下面就是它:

/**
 * Downloads from a given url to a local file
 * @param url url to download
 * @param file local file
 * @param callback called during the download, signature: callback(currentBytes)
 * @returns downloadResult {contentType, error: false | ExceptionObject}
 */
function downloadFromUrl(url, file, callback) {
  let result = {
    contentType: null,
    error: false
  };

  try {
    let channel = chrome.Cc["@mozilla.org/network/io-service;1"]
                    .getService(chrome.Ci.nsIIOService)
                    .newChannel(url, 0, null);

    let bstream = chrome.Cc["@mozilla.org/binaryinputstream;1"]
                    .createInstance(chrome.Ci.nsIBinaryInputStream);
    bstream.setInputStream(channel.open());

    let fos = chrome.Cc["@mozilla.org/network/safe-file-output-stream;1"]
                .createInstance(chrome.Ci.nsIFileOutputStream);
    try {
      // const values from https://developer.mozilla.org/en-US/docs/PR_Open#Parameters
      const PR_RDWR = 0x04; // Open for reading and writing.
      const PR_CREATE_FILE = 0x08; // If the file does not exist, the file is created. If the file exists, this flag has no effect.
      const PR_APPEND = 0x10; // The file pointer is set to the end of the file prior to each write.
      const PR_TRUNCATE = 0x20; // If the file exists, its length is truncated to 0.
      const PR_SYNC = 0x40; // If set, each write will wait for both the file data and file status to be physically updated.

      fos.init(file, PR_RDWR | PR_CREATE_FILE | PR_APPEND | PR_TRUNCATE | PR_SYNC, 0600, 0);

      let length = 0;
      let size = bstream.available();
      while(size) {
        fos.write(bstream.readBytes(size), size);

        length += size;
        callback(length);

        size = bstream.available();
      }

      fos.flush();

      result.contentType = channel.contentType;
    } finally {
      if (fos instanceof chrome.Ci.nsISafeOutputStream) {
        fos.finish();
      } else {
        fos.close();
      }
    }
  } catch (e) {
    result.error = e;
  }

  return result;
}
/**
 * Downloads from a given url to a local file
 * @param url url to download
 * @param file local file
 * @param callback called during the download, signature: callback(currentBytes)
 * @returns downloadResult {contentType, error: false | ExceptionObject}
 */
function downloadFromUrl(url, file, callback) {
  let result = {
    contentType: null,
    error: false
  };

  try {
    let channel = chrome.Cc["@mozilla.org/network/io-service;1"]
                    .getService(chrome.Ci.nsIIOService)
                    .newChannel(url, 0, null);

    let bstream = chrome.Cc["@mozilla.org/binaryinputstream;1"]
                    .createInstance(chrome.Ci.nsIBinaryInputStream);
    bstream.setInputStream(channel.open());

    let fos = chrome.Cc["@mozilla.org/network/safe-file-output-stream;1"]
                .createInstance(chrome.Ci.nsIFileOutputStream);
    try {
      // const values from https://developer.mozilla.org/en-US/docs/PR_Open#Parameters
      const PR_RDWR = 0x04; // Open for reading and writing.
      const PR_CREATE_FILE = 0x08; // If the file does not exist, the file is created. If the file exists, this flag has no effect.
      const PR_APPEND = 0x10; // The file pointer is set to the end of the file prior to each write.
      const PR_TRUNCATE = 0x20; // If the file exists, its length is truncated to 0.
      const PR_SYNC = 0x40; // If set, each write will wait for both the file data and file status to be physically updated.

      fos.init(file, PR_RDWR | PR_CREATE_FILE | PR_APPEND | PR_TRUNCATE | PR_SYNC, 0600, 0);

      let length = 0;
      let size = bstream.available();
      while(size) {
        fos.write(bstream.readBytes(size), size);

        length += size;
        callback(length);

        size = bstream.available();
      }

      fos.flush();

      result.contentType = channel.contentType;
    } finally {
      if (fos instanceof chrome.Ci.nsISafeOutputStream) {
        fos.finish();
      } else {
        fos.close();
      }
    }
  } catch (e) {
    result.error = e;
  }

  return result;
}