【问题标题】:NodeJS using FS and AsyncJS blocking the UINodeJS 使用 FS 和 AsyncJS 阻塞 UI
【发布时间】:2018-11-13 03:56:17
【问题描述】:

我正在使用 react、electron、nodejs、asyncjs redux 和 thunk。 我编写了以下代码,它应该下载文件列表并将其写入磁盘。在我的代码中,当用户按下按钮时,我称之为 actionCreator:

export function downloadList(pack) {
  return (dispatch, getState) => {
    const { downloadManager } = getState();

    async.each(downloadManager.downloadQueue[pack].libs, async (url, callback) => {
      const filename = url.split('/').pop().split('#')[0].split('?')[0];
      await downloadFile(url, `dl/${filename}`);
      callback();
    }, (err) => {
      if (err) {
        console.log('A file failed to process');
      } else {
        dispatch({
          type: DOWNLOAD_COMPLETED,
          packName: pack
        });
      }
    });
  };
}

async function downloadFile(url, path) {
  const file = fs.createWriteStream(path);
  const request = https.get(url, (response) => {
    response.pipe(file);
    file.on('finish', () => {
      file.close();
    });
  }).on('error', (err) => { // Handle errors
    fs.unlink(path); // Delete the file async. (But we don't check the result)
  });
}

它会做它应该做的事情,但是当它这样做时,它会阻塞整个 UI。我真的不明白为什么会这样,因为如果我使用

setTimeout

在 async.each 内有 3000 毫秒的延迟,它不会阻塞 UI。 另一个奇怪的行为是,如果我使用 asyncJS 的 eachLimit 函数,它只会下载文件的限制,所以如果我想下载 100 个文件但我将 eachLimit 设置为 10 个并行,它只会下载前 10 个文件然后停止。你能告诉我这个吗? 我想使用 axios 来下载文件,因为它不需要知道 URL 是 http 还是 https,但是我找不到任何关于使用流响应类型的 axios 的资源

【问题讨论】:

  • 在从`await downloadFile(url, dl/${filename})中删除await之后尝试;`

标签: node.js reactjs asynchronous redux async.js


【解决方案1】:

我可以回答第一部分。几乎所有现有的 JavaScript 实现都运行在一个线程上。这意味着运行时是并发的,但不是并行的,即运行时一次只做一件事。这意味着如果有一个函数调用需要一段时间,它将阻塞其他所有内容。因此,downloadList 函数中的某些东西阻塞了事件循环。但是,如果您使用setTimeout,那么downloadList 函数将被推送到消息队列中,这将解除对事件的阻塞并允许呈现UI。有关事件循环的更多信息,请查看this video

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多