node.js berjanji di for-loop

Saya mencoba menggabungkan beberapa file (dan pembuatan dokumen PDF jika hasil database mengembalikan banyak elemen dengan bidang 'json' yang tidak kosong).

Sekarang penggabungan hanya terjadi sekali dan menggabungkan elemen pertama dengan element['json'] != '' dengan dirinya sendiri.

Merging logic is:

  • semua PDF sudah dibuat, kecuali yang akan kita buat selanjutnya
  • jika suatu elemen berisi beberapa JSON, buat PDF
  • jika suatu elemen tidak mengandung JSON, gabungkan ke PDF sebelumnya
  • Mungkin memasukkan semua janji ke dalam array dan meneruskannya ke Promise.all() membantu? Benar-benar terjebak sekarang.

    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 sumber


    Jawaban (1)


    Anda perlu memperhatikan aliran kendali Anda. Ya, Anda membuat janji tetapi tidak menunggu sampai janji itu dipenuhi. Anda dapat menggunakan sinkronisasi async/await atau perpustakaan Promise seperti bluebird

    Akar masalah cuplikan kode khusus Anda adalah result.recordset.forEach(element => {, yang pada dasarnya berjalan secara sinkron dan kemudian memanggil res.end()

    Entah Anda dapat melakukan semuanya async/await, tetapi Anda mungkin perlu Menjanjikan panggilan request.execute("create_json", callback) itu.

    Atau Anda dapat menggunakan perpustakaan Promise untuk melakukan sesuatu seperti

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

    untuk memastikan semua yang ada di array Anda diproses terlebih dahulu. (Anda juga ingin catch rantai janji itu dengan res.error() atau apa pun sebutannya, dan pastikan Janji Anda kembali sehingga berhasil dirangkai:

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

    Atau untuk melakukan konsolidasi

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

    Ini hanyalah titik awal, tapi semoga bermanfaat bagi Anda.

    person clay    schedule 21.05.2018
    comment
    Saya sudah mencoba mengikuti panduan Anda, tetapi sekarang mengalami masalah, ia mengisi array file[], termasuk semua baris yang dikembalikan dari prosedur tersimpan. Pemeriksaan files.length › 100 gagal. Saya jelas melewatkan sesuatu. Melakukan pengeditan pada postingan asli - person minicooper; 01.06.2018
    comment
    Saya juga kesulitan mengikutinya! Periksa apakah makePDF(), tekad('ok') berbeda dari, dan jangan menunggu, kembalikan 'ok'. Saya menyarankan Anda menambahkan banyak baris console.log di seluruh kode Anda, dan menjalankannya hanya dengan 1 atau 2 file. Lihat bagaimana kode Anda dijalankan, dan lihat setiap nilai saat diproses, terutama awal dari setiap '.then()' dan pintu masuk ke setiap fungsi.. Itu akan membuat Anda melihat apa yang sebenarnya terjadi. Semoga Anda berhasil. - person clay; 02.06.2018