Я пишу приложение node.js, которое позволяет пользователю создавать многостраничные pdf-файлы в node.js.Выполнение нескольких фантомных процессов для множественных запросов асинхронных в Node.js
Я создаю страницы один за другим и передаю отдельные страницы в виде массива с запросом функции для работы до тех пор, пока все страницы не будут созданы, и в это время я использую PDF-слияние для объединения многостраничного документа.
function pdfExport_map(site, siteData, req){
phantom.pdf_export_map(site, siteData, req, pdfExport_census);
}
function pdfExport_census(site, siteData, req){
phantom.pdf_export_census(site, siteData, req, pdfExport_ue);
}
function pdfExport_ue(site, siteData, req){
phantom.pdf_export_ue(site, siteData, req, pdfExport_decay);
}
function pdfExport_decay(site, siteData, req){
phantom.pdf_export_decay(site, siteData, req, processSites);
}
function processSites(req) {
var pdfMerge = new PDFMerge(req.fileStack, 'C:\\Program Files (x86)\\PDFtk\\bin\\pdftk.exe');
var d = Date.now();
var filename = 'r' + d.toString() + '.pdf';
pdfMerge.asNewFile(process.env.FILEPATH + filename).merge(function (error, file) {
console.log(file);
});
}
Это работает достаточно хорошо, если один пользователь запускает процесс. Если несколько пользователей запускают процесс одновременно, только один пользователь получает отчет. Процесс терпит неудачу с фантомными обещаниями. Когда я устанавливаю точки останова в следующей функции, я вижу, что данные для сайта B получены (точка останова 1) до того, как сайт A был экспортирован как PDF (точка останова 2). На этом этапе процесс для сайта B никогда не заберет.
function pdf_export_map(site, siteData, req, _pdfExport_census) {
phantom.create()
.then(instance => {
ph = instance;
return instance.createPage();
})
.then(p => {
page = p;
page.open('about:blank');
})
.then(function() {
var renderTimeout,
c = 0;
function doRender() {
console.log('page loaded');
var d = Date.now();
var filename = 'm' + d.toString() + '.pdf';
page.render('tmp/' + filename)
.then(function() {
//breakpoint 2 page PDF export complete
ph.exit();
req.fileStack.push(process.env.FILEPATH + filename);
_pdfExport_census(site, siteData, req)
});
}
page.on('onResourceRequested', function (r) {
c++;
console.log(('000' + r.id).slice(-4) + ' | ' + r.url);
clearTimeout(renderTimeout);
});
page.on('onResourceReceived', function (r) {
if (!r.stage || r.stage === 'end') {
c--;
console.log(('000' + r.id).slice(-4) + ' | ' + r.status);
if (c === 0) {
renderTimeout = setTimeout(doRender, 5000);
}
}
});
if (process.platform == 'win32') {
page.property('paperSize', {
width: '11in',
height: '8.5in'
});
} else {
page.property('paperSize', {
width: '1056px',
height: '816px'
});
}
page.property('viewportSize', {
width: 1056,
height: 816
});
page.property('clipRect', {
top: 0,
left: 0,
width: 1056,
height: 816
});
//breakpoint 1 data received, start render
ejs.renderFile('views/phantommap.ejs', {
site: site,
features: siteData.features,
subdirectory: process.env.SUBDIRECTORY,
page: req.fileStack.length + 1
}, function (err, html) {
page.setContent(html, 'http://' + process.env.HOST + '/amazon/phantommap');
});
})
.catch(err => {
console.log(err);
ph.exit();
});
}
У меня плохое представление о фантоме и обещаниях. Можно ли запустить этот синхронный, например, завершите страницу для одного сайта, а затем запустите страницу для второго отчета?
Редактировать: Выполнение нескольких тестов Я прокомментировал ph.exit(). Я вижу, что я получаю данные для сайта A и для сайта B. Но страница для сайта A экспортируется дважды.
Редактировать: После рекомендации Амира я получил эту работу, объявив ph и страницу внутри функции так.
phantom.create()
.then(instance => {
_ph = instance;
return instance.createPage();
})
.then(p => {
_page = p;
_page.open('about:blank');
})
.then(function() {
var renderTimeout,
c = 0,
ph = _ph,
page = _page;
Мне все еще нужно изучить использование async и ждать.
Еще раз спасибо за помощь. Модуль phantomjs является удивительным. Посмотрите на использование async и ждите. Приветствия. –
Вы, безусловно, приветствуетесь и благодарны за принятие моего ответа. –
У меня есть вопрос относительно этой проблемы. Это означает, что мы не можем повторно использовать процесс phantomjs.exe для нескольких запросов? Проблема с phantomjs.exe заключается в том, что процесс запуска занимает до 7 секунд, и запросы выполняются быстро. Но если у вас есть 40 запросов на выполнение, вы можете рассчитать, сколько времени это, по крайней мере, займет ... слишком много. – Legends