Определение асинхронной функции и ее использование в цикле forEach - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь скомпилировать текс-файлы в PFD, используя данные из базы данных firestore.После завершения скрипт не завершается.Я нашел, что можно использовать process.exit (), чтобы заставить его выйти.Тем не менее, это завершает дочерние процессы, все еще сжимающие текстовые файлы.Итак, мне нужна асинхронная функция.Руководства, которые я нашел по их изготовлению, мне не особо помогли.Я все еще очень новичок в javascript, и любое раздувание все еще сильно сбивает меня с толку.

Руководства, которые я нашел, как их сделать, не особенно помогли мне.Я все еще очень плохо знаком с javascript, и любое раздувание все еще сильно сбивает меня с толку.добавление нижеприведенной функции makePDF с помощью async, а вызов функции с помощью await не работает и, насколько я понимаю, устарело.Я пытался реализовать обещание, но не понимаю, как работает их синтаксис.Достаточно ли простого добавления .then () к вызову функции в цикле for, чтобы цикл ожидал завершения функции?Как сделать этот конкретный асинхронный?Имеет ли значение, что он уже использует асинхронные функции в своем теле?Я понимаю, что обещание используется для возврата того, что производитель произвел для потребителя.Теперь мой продюсер не производит ничего для возврата.Имеет ли это значение вообще?

Моя функция вызывается из цикла for:

function makePDF(object){
    let input = fs.readFileSync('main.tex', 'utf8');
    const outNameTex = object.ID + '.tex';
    const outNamePDF = object.ID + '.pdf';

    makeTEX(object, input, outNameTex);

    const infile = fs.createReadStream(outNameTex);
    const outfile = fs.createWriteStream(outNamePDF);
    const pdf = latex(infile);

    pdf.pipe(outfile);
    pdf.on('error', err => console.error(err));
    pdf.on('finish', () => {console.log('PDF generated!')});
}

И моя функция с циклом:

firebase.auth().onAuthStateChanged((user) => {
    if (user) {
      console.log('user');
      db.collection('objects').where('printed', '==', false).get().then((snapshot) => {
        snapshot.forEach((doc) => {
          console.table(doc.data());
          makePDF(doc.data());
          })
          process.exit();
        })
      .catch((err) => {
        console.log('Error getting documents', err);
      });
    } else {
      console.log('no user');
    }
});

Выводит таблицу длякаждый документ, но не PDF generated.

1 Ответ

0 голосов
/ 16 апреля 2019

async / await может быть сложно использовать для циклов for, потому что асинхронные функции возвращают обещание ... если вы преобразуете синтаксис async / await в собственный синтаксис обещания, вы можете выяснить, в чем проблема.

Что вы хотите сделать, это использовать Array.map, чтобы отобразить / преобразовать каждый документ в обещание, которое разрешается после выполнения makePDF, затем используйте Promise.all, чтобы дождаться разрешения всех обещаний.

Решение должно выглядеть примерно так

function makePDF(object){
  return new Promise((resolve, reject) => {
    let input = fs.readFileSync('main.tex', 'utf8');
    const outNameTex = object.ID + '.tex';
    const outNamePDF = object.ID + '.pdf';

    makeTEX(object, input, outNameTex);

    const infile = fs.createReadStream(outNameTex);
    const outfile = fs.createWriteStream(outNamePDF);
    const pdf = latex(infile);

    pdf.pipe(outfile);
    pdf.on('error', reject);
    pdf.on('finish', () => {console.log('PDF generated!'); resolve();});
}
firebase.auth().onAuthStateChanged((user) => {
    if (user) {
      console.log('user');
      db.collection('objects').where('printed', '==', false).get().then((snapshot) => {
        const promiseArr = snapshot.docs.map((doc) => {
          console.table(doc.data());
          return makePDF(doc.data());
          })
          Promise.all(promiseArr)
            .then(() => {
              process.exit();
            })
        })
      .catch((err) => {
        console.log('Error getting documents', err);
      });
    } else {
      console.log('no user');
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...