node.js обещает цикл for - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь добиться объединения нескольких файлов (и создания документов PDF, если результат базы данных возвращает несколько элементов с непустым полем 'json').

Теперь объединение происходит только один раз и объединяетпервый элемент с element['json'] != '' с самим собой.

Логика слияния:

все PDF-файлы созданы недавно, за исключением того, что мы создадим следующие , если элемент содержит некоторый JSON, создайте PDF , еслиэлемент не содержит JSON, объедините его с предыдущим PDF

Может быть, вставка всех обещаний в массив и передача их в Promise.all () поможет?Действительно застрял сейчас.

app.get("/api/generatePDF", jsonParser, function(req, res) {

var saveFilename, savePath;
var idDocument, idPatient, idDoctor, idItem;
var orientation = "";
var url = req.route.path;
var tbl = "";
var html = "";
var hasTables = 0;
console.log(req.query.json);
var savedJSON = JSON.parse(req.query.json);
var flag = 4;
var id_inventory = parseInt(savedJSON['id_inventory']);
var request = new sql.Request();
var files = new Array();
var badFiles = new Array();
var options = "";
var mergeNeeded = parseInt(savedJSON['param']);
if (mergeNeeded == 1) {
    flag = 14;
}
var cnt = 0;
var output = parseInt(savedJSON['output']);
var mergedName = savedJSON['merged_name'];
var numRows = 0;
var idSpec = mergeNeeded;
if (id_inventory == 0) {
    var pid = savedJSON['id_patient'];
    var idDocType = savedJSON['id_doc_type'];
    idSpec = savedJSON['id_spec'];
    flag = 10;
    request.input('id_patient', sql.Int, pid);
    request.input('id_doc_type', sql.Int, idDocType);
}
request.input('id_spec', sql.Int, idSpec);
request.input('flag', sql.Int, flag);
request.input('redo', sql.Int, 1);
request.input('id_inventory', sql.Int, id_inventory);

request.execute("create_json").then(function(result) {
    var size = result.recordset.length;
    return Promise.all(result.recordset.map(function(element) {

            savePath = element['path'];
            idItem = element['id_item'];
            saveFilename = element['filename'];
            options = { "format": "A4", "orientation": element['orientation'], "renderDelay": "undefined", "border": "10mm" }
            idPatient = element['id_patient'];
            htmlFile = element['id_template'];
            var fillTemplate = new Promise((resolve, reject) => {
                files.push(basePath + element['path'] + separator + element['filename']);
                if (element['json'] != "") {
                    fs.readFile('templates' + separator + element['id_template'] + '.html', 'utf8', function(err, data) {
                        if (err) {
                            return console.log(err);
                            reject(err);
                        }
                        html = data;
                       // filling the template
                        resolve(html);
                    });
                }
            });
            var makeDirectory = new Promise((resolve, reject) => {
                if (element['json'] != "") {
                    mkdirp(basePath + element['path'], function(err) {
                        if (err) {
                            reject(err);
                        }
                        resolve(element);
                    });
                }
            });

            var makePDF = (html) => {
                return new Promise((resolve, reject) => {
                    if (element['json'] != "") {
                        pdf.create(html, options).toFile(basePath + element['path'] + separator + element['filename'], function(err, res) {
                            if (err) {
                                console.log(err);
                                reject(err);
                            } else {                                   
                                var request2 = new sql.Request();
                                request2.input('flag', sql.Int, 5);
                                request2.input('id_inventory', sql.Int, element['id_item']);
                                request2.execute("PDF_create_json", (err2, result2) => {});                                    
                            }

                            if (mergeNeeded == 1) {
                                if ((files.length > 100) || (files.length == size)) {
                                    PDFMerge(files, { output: basePath + mergedName }).then(() => {
                                        files.length = 0;
                                        files.push(basePath + mergedName);
                                        return "OK";
                                    })
                                }
                            } resolve("OK");
                        });
                    } else {

                        if (mergeNeeded == 1) {
                            if ((files.length > 100) || (files.length == size)) {
                                PDFMerge(files, { output: basePath + mergedName }).then(() => {
                                    files.length = 0;
                                    files.push(basePath + mergedName);
                                    return "OK";
                                })
                            }
                            console.log("mergedname: " + mergedName);
                            console.log("Files have been merged");
                            resolve("OK");
                        }
                    }

                });
            };
            return makeDirectory
                .then(() => {
                    return fillTemplate
                })
                .then(makePDF)
                .then(() => {
                    console.log(files);
                })
        }

    ))
}).then(results => {
    res.end("all done");
})

});

1 Ответ

0 голосов
/ 21 мая 2018

Вам нужно следить за потоком управления.Да, вы создаете обещания, но не ожидаете их выполнения.Вы можете использовать async/await sync или библиотеку Promise, например bluebird

Основная проблема вашего конкретного фрагмента кода - result.recordset.forEach(element => {, который, в основном, выполняется синхронно, а затем вызывает res.end()

Либо вы можете сделать все async/await, но вам, возможно, придется обещать, что request.execute("create_json", callback) вызов.

Или вы можете использовать библиотеку Promise, чтобы сделать что-то вроде

Promise.each(result.recordset, function returnAPromise(){
  // your stuff here. Make sure this returns a Promise (chain)
})
.then(results => { 
  // now call res.end() 
})

, чтобы убедиться, что все в вашем массиве обрабатывается первым.(Вы также захотите catch эту цепочку обещаний с res.error() или любым другим вызовом, и убедитесь, что ваши Обещания возвращаются, чтобы они были успешно соединены:

return makeDirectory.then(() => {
            return fillTemplate.then(result => {
                return makePDF(result).then(() => {
                     console.log("");
                });
            });
        });

Или объединить

return makeDirectory
.then(() => {
   return fillTemplate
})
.then(makePDF)
.then(() => { console.log('here') } )

Это только отправная точка, но, надеюсь, вы найдете ее полезной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...