[英]Passing data between middleware logs correctly but returns undefined inside object
我正在兩個表達中間件之間傳遞數據,因為我的變量之一是在函數(中間件1)中設置的,需要在其功能范圍之外(在中間件2中)進行訪問。 當我在第二個中間件中使用console.log req.invoice時,它會正確記錄日志,因此我知道我已正確地在中間件之間傳遞了數據,但是當嘗試使用變量在第二個中間件中構造新對象時,req.invoice是未定義。
var express = require('express');
var app = express();
var Invoice = require('../models/Invoice');
var router = express.Router();
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var expressValidator = require('express-validator');
var fs = require('fs');
//Used to create a pdf invoice
var PDFDocument = require('pdfkit');
//Route
router.route('/:item')
.post(generateInvoice, sendMail, function(req, res){
});
//First middleware
var fileName, dest, invoiceNr;
function generateInvoice (req, res, next) {
//Destination for storing the invoice file
dest = __dirname + '/../static/';
//generate invoice nr
Invoice.find(function(err, invoices){
if(err) {
return res.send(err);
} else {
invoiceNr = invoices.length + 1;
fileName = 'invoice' + invoiceNr + '.pdf';
req.invoicePath = path.resolve(dest + fileName);
generate();
}
});
//Create the invoice and store in static directory
function write() {
doc = new PDFDocument();
doc.pipe(fs.createWriteStream(dest + fileName));
doc.text(invoice, 100, 100);
console.log('File written > ' + fileName + '\n Destination: ' + dest);
doc.end();
}
function generate (err){
if (err)
throw err;
if (invoiceNr !== undefined) {
write();
}
}
next();
}
//Second middleware
//I'm using mailgun-js to send the invoice via email
function sendMail(req, res, next){
//Mailgun implementation
var api_key = 'MY_KEY';
var domain = 'MY_DOMAIN';
var mailgun = require('mailgun-js')({apiKey: api_key, domain: domain});
var data = {
from: 'APP_MAIL',
to: 'example@mail.com',
subject: 'Hello',
text: 'Should include attachment!',
//req.invoicePath is undefined when it should be a filepath
attachment: req.invoicePath
//when invoicePath was set as a static string, the attachment was included in the email
//attachment: '/Users/anton/Desktop/app/src/server/static/invoice27.pdf'
};
//again I'm using mailgun-js for sending the emails
mailgun.messages().send(data, function (error, body) {
console.log('Message body: ' + body);
//This works and I get the above: '/Users/anton/Desktop...' in the console
console.log('The path to the invoice: ' + req.invoicePath);
//Works properly as well
console.log('The path is of type: ' + typeof(req.invoicePath));
});
res.end();
}
我已經將req.invoicePath設置為這是我的第一個中間件。
req.invoicePath = path.resolve(dest + fileName);
可以在mailgun博客上找到有關如何使用mailgun發送電子郵件的簡要說明,非常感謝任何幫助,謝謝!
您有異步計時問題。 在您的第一個中間件中,您要在Invoice.find()
函數完成之前調用next()
,從而在設置req.invoicePath
之前執行第二個中間件。
要解決此問題,僅在完成第一個中間件中的異步操作后才調用next()
。 您還需要將變量移到generateInvoice()
內,以便它們是受保護的局部變量,並且不會被同時在運行的另一個請求所截斷:
function generateInvoice (req, res, next) {
var fileName, dest, invoiceNr;
//Destination for storing the invoice file
dest = __dirname + '/../static/';
//generate invoice nr
Invoice.find(function(err, invoices){
if(err) {
return res.send(err);
} else {
invoiceNr = invoices.length + 1;
fileName = 'invoice' + invoiceNr + '.pdf';
req.invoicePath = path.resolve(dest + fileName);
generate();
// move next() here so it is not called until after req.invoicePath is set
next();
}
});
//Create the invoice and store in static directory
function write() {
var doc = new PDFDocument();
doc.pipe(fs.createWriteStream(dest + fileName));
doc.text(invoice, 100, 100);
console.log('File written > ' + fileName + '\n Destination: ' + dest);
doc.end();
}
function generate (err){
if (err)
throw err;
if (invoiceNr !== undefined) {
write();
}
}
}
由於我假設write()
可能包含一些異步部分,因此這里也可能存在其他異步問題。 並且,您顯示了一個generate()
參數,但沒有傳遞參數。 而且,如果generate()
執行了throw err
,那么您將沒有任何處理程序來執行某些智能操作。
我所做的更改:
next()
移動到Invoice.find()
回調內部,以便在設置req.invoicePath
之后才調用它。 generateInvoice()
函數中為fileName, dest, invoiceNr
移動的變量聲明,因此對於函數的每次調用它們都是唯一的,並且同時進行中的其他請求不會刪除其值。 其他潛在問題:
generate()
接受一個err參數,但沒有將其傳遞給它。 generate()
的throw err
不會被捕獲並且做任何有用的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.