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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать 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-строки, если я говорю коду ждать ее?
Вы исходите из предположения, что Object.keys(setter).forEach() завершил обновление данных до того, как будет выполнен оставшийся код. Но единственное, что вы можете гарантировать, это то, что обратный вызов вызывается для каждого элемента. Вы не ждете завершения обратных вызовов, прежде чем продолжить. Возможно, вы захотите рассмотреть возможность последовательного использования Promises и, когда окончательное обещание будет выполнено, выполнить код, который должен следовать.
readFileSync является синхронным вызовом, пока чтение не будет завершено, оно не будет продолжено. консоль читает данные после чтения.