Как мне регистрировать ответы в правильном порядке, используя асинхронный код - PullRequest
0 голосов
/ 15 января 2019

Мне нужно создать функцию, которая запускает функцию getFile для каждого элемента в массиве. Функция getFile регистрирует «содержимое файла x» x, являющееся любым элементом в массиве.

В настоящее время у меня есть рабочая функция, которая запускает getFile для массива и ждет окончательного ответа, прежде чем регистрировать результаты.

Однако теперь мне нужно регистрировать ответы по мере их поступления. Например, если мой массив [1, 2, 3, 4, 5], в настоящее время он записывает «Содержимое файла x» в случайном порядке, поэтому, если он должен вернуть журналы, 3, затем 4, а затем 1. Как только Я получаю 1, мне нужно войти в систему, затем, как только я получаю 2 журнала, и так далее.

Я вставлю свой текущий код ниже. Проблема, с которой я столкнулся, заключается в том, что мне нужно знать, когда «пустое пространство» в моем массиве заполняется, чтобы я мог записывать его в реальном времени. Поэтому, позволяя моему пользователю увидеть результат, а не ждать, пока все ответы вернутся

function fetchContentOfFiles(fileNames, testCB) {
  const fileContent = [];
  let counter = 0;

  fileNames.forEach((file, i) => {
    getFile(file, (err, fileName) => {
      if (err) console.log(err)
      else {
        fileContent[i] = fileName;
        counter++
        if (counter === fileNames.length) {
          testCB(null, fileContent)
        };
        console.log(fileContent)
      };
    });
  });
};

1 Ответ

0 голосов
/ 17 января 2019

Самый простой способ написать это - использовать цикл for внутри функции async. Обещайте getFile, чтобы он возвращал Promise, а затем ожидайте его на каждой итерации цикла. В конце цикла вызовите обратный вызов:

const getFileProm = file => new Promise((resolve, reject) => {
  getFile(file, (err, fileName) => {
    if (err) reject(err);
    else resolve(fileName);
  });
});

async function fetchContentOfFiles(fileNames, testCB) {
  const fileContent = [];
  try {
    for (let i = 0; i < fileNames.length; i++) {
      fileContent.push(
        await getFileProm(fileNames[i])
      );
    }
  } catch(e) {
    // handle errors, if you want, maybe call testCB with an error and return?
  }
  testCB(null, fileContent);
}

Вероятно, было бы даже лучше, если бы fetchContentOfFiles был вызван и обработан как Обещание , а не с обратными вызовами, и тогда ошибки могут быть обработаны потребителем:

async function fetchContentOfFiles(fileNames) {
  const fileContent = [];
  for (let i = 0; i < fileNames.length; i++) {
    fileContent.push(
      await getFileProm(fileNames[i])
    );
  }
  return fileContent;
}

fetchContentOfFiles(arr)
  .then((fileContent) => {
    // do stuff with fileContent
  })
  .catch((err) => {
    // something went wrong
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...