2017-01-03 72 views
2

任務:從數據庫獲取查詢=>生成多個pdf =>通過節點js發送郵件附件 問題:這裏的問題是在生成pdf之前我的sendMail()函數被調用。那麼如何在所有pdf生成之後才能調用sendMail函數?節點js發送PDF格式的電子郵件作爲同步附件

pdfs = []; 

// Pdf generate code 
var generatePdf = function (rows) { 
    return new Promise(function (resolve, reject) { 
     for (var i = 0; i < rows.length; i++) { 
      html = ejs.renderFile(
       'views/voucher.ejs', 
       { 
        voucher: rows[i] 
       }, 
       function (error, success) { 
        if (error) { 
         console.log(error); 
        } else { 
         var pdf_path = '/srv/ voucher/uploads/voucher/' + Math.random().toString(36).substring(7) + '.pdf'; 

         htmlToPdf.convertHTMLString(success, pdf_path,  function (error, success) { 
          if (error) { 
           console.log('Oh noes! Errorz!'); 
           console.log(error); 
          } else { 
           pdfs.push(pdf_path); 
           console.log("Single"); 
           console.log(pdfs); 
           console.log('Woot! Success!'); 
          } 
         }); 
        } 
       }); 
      } 
      resolve(); 
    }); 
} 

// send mail code 
var sendMail = function() { 
    new Promise(function (resolve, reject) { 

     console.log("All" + pdfs); 
     pdfs.forEach(function (value, key) { 
      // mail sending code 
     }); 
    }); 
}; 


var findVoucherAndSendMail = function() { 
    return new Promise(function (resolve, reject) { 

     var query = con.query('SELECT * FROM voucher limit 20', function selectAll(err, rows, fields) { 
      if (err) { 
       throw err; 
      } 

      resolve(rows); 

     }); 

    }); 
}; 

findVoucherAndSendMail().then(function (fromResolve) { 
    return generatePdf(fromResolve); 
}).then(function() { 
    return sendMail(); 
}).catch(function() { 
}); 
+0

它不會解決您的問題,但您不會在sendMail中返回承諾 – MatthieuLemoine

+0

我測試了您的代碼並且無法再現您的問題。你確定sendMail之前被調用過嗎? – MatthieuLemoine

+0

是的,我沒有寫我的pdf生成代碼生成PDF功能它需要大約3至5秒,所以sendmail被稱爲pdf生成之前。 –

回答

1

你的問題是鏈接到一個異步行爲生成pdf時的for循環。 您的承諾在您的pdf生成之前已解決。 您應該使用Promise.all等待生成完成。

function generatePdf(rows) { 
    return Promise.all(rows.map(row => asyncPdfGeneration(row)); 
} 

function asyncPdfGeneration(row) { 
    return new Promise(function (resolve, reject) { 
    ...generate pdf 
    resolve(pdf); 
    } 
} 
+0

其工作。謝謝 :) –

0

第二屆 '然後' 是你的函數findVoucherAndSendMail(),這樣既generatePdf()與sendmail()將觸發一次findVoucherAndSendMail()完成。

放在generatePdf()

findVoucherAndSendMail().then(function (fromResolve) { 
    return generatePdf(fromResolve).then(function() { 
     return sendMail(); 
    }); 
}).catch(function() { 
}); 

編輯二號 '然後'

你嘗試:resolve(pdfs);,而不是僅僅resolve();

+0

不是真的......你可以並應該鏈接承諾,以避免回調地獄 – MatthieuLemoine

+0

@MatthieuLemoine瞭解。但是,考慮到他對Promise的瞭解不多,這應該解決他眼前的問題。 – zerohero

相關問題