Функция, которая анализирует список пройденных путей - PullRequest
3 голосов
/ 08 марта 2020

Мне нужна асинхронная функция "getTypes", которая анализирует список пройденных путей и возвращает массив, описывающий, что находится в каждом из путей. Функция должна хорошо работать в любом случае. Если во время асинхронной операции возникает ошибка, значение для этого пути - «ноль». Я пытался написать функцию, но она не работает.

const getTypes = (arr) => {
  const prom = arr.reduce((acc, path) => (
    acc.then((data) => {
       return fs.stat(path).isFile() ? 'file' : 'directory';
     })
    .catch(() => null)
  ), Promise.resolve());
  return prom;
}

Как это должно работать:

getTypes(['/etc', '/etc/hosts', '/undefined']).then(console.log);
// ['directory', 'file', null]

Не знаете, как это сделать, кто-нибудь может помочь? плз

1 Ответ

2 голосов
/ 08 марта 2020

Подход 1

async function getTypes(arr) { // Mark the function as async
   return Promise.all(arr.map(async (path) => { // Promise.all will wait for all mapped calls to be resolved
      try {
          const stat = await fs.stat(path) // fs.stat is async
      } catch(e) {
          return null
      }
      return stat.isFile() ? 'file' : 'directory';
   }));
}

Подход 2: (модификации кода ОП)

const getTypes = arr => {
  const prom = arr.reduce((acc, path) => {
    acc
      .then(data => {
        return Promise.all([fs.stat(path), Promise.resolve(data)]);
      })
      .then(([stat, data]) =>
        stat.isFile()
          ? [Promise.resolve(data.push("file")), false]
          : [Promise.resolve(data.push("directory")), false]
      )
      .catch(() => Promise.resolve([data, true])) // so the next `then` can have access to data
      .then([data, failed] => failed === true ? Promise.resolve(data.push(null)) : Promsie.resolve(data)
  }, Promise.resolve([]));
  return prom;
};

Подход 3: (не отказоустойчив. Т.е. Promise.all не будет работать, если в любом из асин c вызовов возникнет ошибка):

function getTypes(arr) {
  const deferreds = arr.map(fs.stat);
  return Promise.all(deferreds).then(stats =>
    stats.map(stat => (stat.isFile() ? "file" : "directory"))
  );
}

Подход 4: ( Немного изменив # 3, чтобы сделать его отказоустойчивым)

const getFileType = stat => stat.isFile() ? 'file' : 'directory'
const getFileStat = path => fs.stat(path).then(getFileType).catch(() => null)
const getTypes = paths => Promise.all(paths.map(getFileStat))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...