NodeJS Html-pdf: fs.readfilesync как асинхронно/ожидать

У меня проблема с созданием документа html-pdf. Проблема в том, что часто код работает слишком быстро, чтобы завершить процесс создания pdf-документа. Процессы состоят из построения строки HTML путем замены заполнителей в файле HTML. Ниже вы видите код, что происходит потом.

                            Object.keys(setter).forEach(function(element, key, _array) {
                              var regex = new RegExp(element, "g");

                              data = data.replace(regex, setter[element])
                            })

                            var result = data;

                            fs.writeFile(mergeFileRes, result, 'utf8', function (err) {
                                if (err) { 
                                    console.info(err); 
                                    return;
                                } else {

                                    let html2 = fs.readFileSync(mergeFileRes, 'utf8');
                                    let options = { 
                                        format: 'a4' , 
                                        "directory" : "/tmp",
                                    };                            

                                    if (html2){
                                        pdf.create(html2, options).toStream(function(err, stream2){
                                            if (err)  console.info(err);
                                            stream2.pipe(res);

                                            stream2.on('end', function () {
                                                try{
                                                    fs.unlink(mergeFileRes)
                                                    console.info(3090, "deleted file");
                                                }
                                                catch (err){
                                                    console.info(3090, "Did not delete file");
                                                }
                                            });
                                        });
                                    } else {

                                    }
                                }
                            });

Моя проблема в том, что во многих случаях переменная html2 еще не создана до запуска процесса pdf.create. Вероятно, это связано с тем, что readFileSync занимает слишком много времени.

Мне было интересно, как я могу это исправить. Как я могу заставить pdf.create ждать завершения readFileSync и заполнения переменной html2.

readFileSync является синхронным вызовом, пока чтение не будет завершено, оно не будет продолжено. консоль читает данные после чтения.

AZ_ 01.02.2019 12:33
Вероятно, это связано с тем, что readFileSync занимает слишком много времени. - нет, функция синхронная, как следует из названия. Проблема в другом,
Estus Flask 01.02.2019 12:34

Значит, функция object.keys/data.replace может выполняться слишком долго? Я думаю, вы можете быть правы. Но как я могу заставить код ждать завершения этого процесса?

RutgerBrns 01.02.2019 12:47
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
3 284
1

Ответы 1

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

Object.keys(setter).forEach(function(element, key, _array) {
    var regex = new RegExp(element, "g");

    data = data.replace(regex, setter[element])
})

var result = data;

fs.writeFile(mergeFileRes, result, 'utf8', function (err) {
    if (err) { 
        console.info(err); 
        return;
    } else {

        fs.readFile(mergeFileRes, 'utf8', function(err, html2){
            if (err) throw err;

            let options = { 
                format: 'a4' , 
                "directory" : "/tmp",
            };                            

            pdf.create(html2, options).toStream(function(err, stream2){
                if (err)  console.info(err);
                stream2.pipe(res);

                stream2.on('end', function () {
                    try{
                        fs.unlink(mergeFileRes)
                        console.info(3090, "deleted file");
                    }
                    catch (err){
                        console.info(3090, "Did not delete file");
                    }
                });
            });
        });
    }
});

Спасибо за ответ. Код работает, но время от времени появляется эта ошибка: GET /api/bill/pdf/5c52eba76369863df45f5712 200 2043.263 ms -- assert.js:42 throw new errors.AssertionError({ ^ AssertionError [ERR_ASSERTION]: html-pdf: Can не создавайте pdf без html-строки Как может по-прежнему не быть html-строки, если я говорю коду ждать ее?

RutgerBrns 01.02.2019 12:44

Вы исходите из предположения, что Object.keys(setter).forEach() завершил обновление данных до того, как будет выполнен оставшийся код. Но единственное, что вы можете гарантировать, это то, что обратный вызов вызывается для каждого элемента. Вы не ждете завершения обратных вызовов, прежде чем продолжить. Возможно, вы захотите рассмотреть возможность последовательного использования Promises и, когда окончательное обещание будет выполнено, выполнить код, который должен следовать.

Dan Nagle 01.02.2019 13:41

Другие вопросы по теме