Javascript порядок выполнения с использованием функций Node fs - PullRequest
0 голосов
/ 16 января 2020

Я пытался заставить следующий код работать так, как мне хотелось бы. Это вывод на консоль 1 2 3.

const fs = require('fs');

const doSomthingWithFile = (file, number) => {
  fs.readFile(file, () => {
    console.log(number);
  });
};

fs.readdir('./', (err, files) => {
  for (let i = 0; i < files.length; i++) {
    doSomthingWithFile(files[i], 1);
  }
  for (let i = 0; i < files.length; i++) {
    doSomthingWithFile(files[i], 2);
  }
});

console.log(3);

Я пытался использовать async / await и функции, которые возвращают обещания, но я предполагаю, что я все делаю неправильно, так как получаю 3 1 2 Как вывод.

Как бы убедиться, что все это выполняется в том порядке, в котором я хотел бы. Это означает, что сначала прочитайте каталог. Затем дождитесь окончания первого doSomthingWithFile(), затем запустите второй и дождитесь последнего оператора журнала, пока не завершится обратный вызов readdir()? 1010 *

Как я уже говорил, я в основном пытался искать на этом сайте для подобных тем, но все еще не может заставить это работать. Например, создание функций обратного вызова asyn c и ожидание функций внутри него не работало (или я, должно быть, делал это неправильно).

Ответы [ 2 ]

1 голос
/ 16 января 2020

Если вы хотите, чтобы он был синхронным, используйте синхронные методы (fs.readdirSync и fs.readFileSync). Ниже async/await версия:

const fsp = require('fs').promises;

const doSomthingWithFile = async (file, number) => {
  await fsp.readFile(file);
  console.log(number);
};

(async () => { // ugly async iife since global await is not supported yet

  const files = await fsp.readdir('./');

  for (let i = 0; i < files.length; i++) {
    await doSomthingWithFile(files[i], 1);
  }

  for (let i = 0; i < files.length; i++) {
    await doSomthingWithFile(files[i], 2);
  }

  console.log(3);
})();
0 голосов
/ 16 января 2020

Если вы сделаете так, чтобы ваша функция doSomethignWithFile возвращала обещание, вы можете ожидать его так, что следующая итерация не будет никогда выполняться до тех пор, пока предыдущая не будет разрешена. Примерно так должно работать:

const fs = require('fs');

const doSomthingWithFile = (file, number) => new Promise((resolve, reject) => {
  fs.readFile(file, () => {
    console.log(number)
    resolve()
  });
});

fs.readdir('./', async (err, files) => {
  for (let i = 0; i < files.length; i++) {
    await doSomthingWithFile(files[i], 1);
  }
  for (let i = 0; i < files.length; i++) {
    await doSomthingWithFile(files[i], 2);
  }
});

Что здесь происходит:

  • обратный вызов readdir сделан asyn c
  • doSomthingWithFile функция возвращает обещание, которое разрешается, когда Асинхронная функция readFile завершена. Мы делаем это, вызывая метод resolve в функции обратного вызова функции readFile.
  • ожидайте возврата от вызовов doSomthingWithFile. Это обеспечивает последовательность, в которой выполняются операции, является последовательной.
...