node.js สัญญาใน for-loop

ฉันกำลังพยายามรวมหลายไฟล์เข้าด้วยกัน (และการสร้างเอกสาร PDF หากผลลัพธ์ของฐานข้อมูลส่งคืนองค์ประกอบหลายรายการโดยมีฟิลด์ 'json' ที่ไม่ว่างเปล่า)

ขณะนี้การผสานเกิดขึ้นเพียงครั้งเดียวและรวมองค์ประกอบแรกด้วย element['json'] != '' เข้ากับตัวมันเอง

Merging logic is:

  • 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");
    })
    

    });


    person minicooper    schedule 21.05.2018    source แหล่งที่มา


    คำตอบ (1)


    คุณต้องดูโฟลว์การควบคุมของคุณ ใช่ คุณกำลังสร้างสัญญาแต่ไม่ได้รอให้สัญญาเสร็จสมบูรณ์ คุณสามารถใช้ 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() หรืออะไรก็ตามที่โทรมา และตรวจสอบให้แน่ใจว่า Promises ของคุณกลับมาเพื่อให้สามารถผูกมัดได้สำเร็จ:

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

    หรือจะรวมตัว

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

    นี่เป็นเพียงจุดเริ่มต้น แต่หวังว่าคุณจะพบว่ามีประโยชน์

    person clay    schedule 21.05.2018
    comment
    ฉันได้พยายามทำตามคำแนะนำของคุณแล้ว แต่ตอนนี้มีปัญหา มันเติมเต็มอาร์เรย์ของไฟล์ [] รวมถึงแถวทั้งหมดที่ส่งคืนจากขั้นตอนการจัดเก็บด้วย การตรวจสอบ files.length › 100 ล้มเหลว เห็นได้ชัดว่าฉันพลาดบางสิ่งบางอย่างไป แก้ไขข้อความเดิมแล้ว - person minicooper; 01.06.2018
    comment
    ฉันก็ติดตามยากเหมือนกัน! ตรวจสอบว่า makePDF(), solve('ok') แตกต่างจากและไม่รอการส่งคืน 'ok' ฉันขอแนะนำให้คุณเพิ่มบรรทัด console.log จำนวนมากตลอดโค้ดของคุณและรันด้วยไฟล์เพียง 1 หรือ 2 ไฟล์เท่านั้น ดูว่าโค้ดของคุณทำงานอย่างไร และดูทุกค่าในขณะที่ประมวลผล โดยเฉพาะจุดเริ่มต้นของทุกๆ '.then()' และการเข้าสู่ทุกฟังก์ชัน... ซึ่งจะทำให้คุณเห็นว่าเกิดอะไรขึ้นจริงๆ หวังว่าคุณจะทำให้มันใช้งานได้ - person clay; 02.06.2018