NodeJS использует FS и AsyncJS блокирует пользовательский интерфейс - PullRequest
0 голосов
/ 03 июня 2018

Я использую реагирую, электрон, 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)
  });
}

Он делает то, что должен делать, но при этом блокирует весь пользовательский интерфейс.Я действительно не могу понять, почему это происходит, потому что если я использую

setTimeout

с задержкой 3000 мс внутри async.each, он не блокирует пользовательский интерфейс.Другое странное поведение заключается в том, что если я использую функцию eachLimit asyncJS, он просто загружает мне лимит файлов, поэтому, если я хочу загрузить 100 файлов, но я устанавливаю для каждого лимита значение 10 параллельно, он просто загружает первые 10 файлов и затем останавливается.Можете ли вы рассказать мне об этом?Я хотел использовать axios для загрузки файлов, так как ему не нужно знать, являются ли URL-адреса http или https, но я не могу найти какой-либо ресурс по использованию axios с потоком responsetype

1 Ответ

0 голосов
/ 03 июня 2018

Я могу ответить на первую часть.Практически каждая существующая реализация JavaScript работает в одном потоке.Это означает, что среда выполнения является параллельной, но не параллельной, т. Е. Среда выполнения выполняет одно и ровно одно действие за раз.Это означает, что если вызов функции занимает некоторое время, он заблокирует все остальное.Поэтому что-то в функции downloadList блокирует цикл обработки событий.Однако, если вы используете setTimeout, функция downloadList будет помещена в очередь сообщений, что разблокирует событие и позволит визуализировать пользовательский интерфейс.Для получения дополнительной информации о цикле событий посмотрите это видео

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...