调用回调done()
时,NodeJS Async.js出现问题。它告诉我“回调已被调用” 。
这是错误:
node_modules/async/dist/async.js:966
if (fn === null) throw new Error("Callback was already called.");
^
Error: Callback was already called.
at /Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/async/dist/async.js:966:32
at /Users/lilianbideau/NodeDashboard/NodeJSAPI/dist/server/api/order/order.controller.js:245:23
at tryRender (/Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/express/lib/application.js:642:5)
at Function.render (/Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/express/lib/application.js:592:3)
at ServerResponse.render (/Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/express/lib/response.js:1008:7)
at myThirdFunction (/Users/lilianbideau/NodeDashboard/NodeJSAPI/dist/server/api/order/order.controller.js:240:7)
at nextTask (/Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/async/dist/async.js:5324:14)
at next (/Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/async/dist/async.js:5331:9)
at /Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/async/dist/async.js:969:16
at mySecondFunction (/Users/lilianbideau/NodeDashboard/NodeJSAPI/dist/server/api/order/order.controller.js:232:10)
at nextTask (/Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/async/dist/async.js:5324:14)
at next (/Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/async/dist/async.js:5331:9)
at /Users/lilianbideau/NodeDashboard/NodeJSAPI/node_modules/async/dist/async.js:969:16
at RandomBytes.ondone (/Users/lilianbideau/NodeDashboard/NodeJSAPI/dist/server/api/order/order.controller.js:226:12)
[nodemon] app crashed - waiting for file changes before starting...
当我按照此处的文档操作时,它应该可以正常工作:https://caolan.github.io/async/docs.html#waterfall
您可以看到回调函数已被调用多次,并且我没有在函数中使用循环。
代码如下:
function create(req, res) {
var order = new _order2.default(req.body);
order.user = req.user.id;
var datedata = new Date();
datedata = Date.now();
order.userNotification.push({ 'status': 'Thank you for your order',
'time': datedata });
order.userNotification.push({ 'status': 'Waiting for your order to be processed.',
'time': datedata });
if (req.body.paymentOption == 'COD') {
order.userNotification.push({ 'status': 'Awaiting confirmation from vendor.',
'time': datedata });
}
order.paymentOption = req.body.paymentOption;
order.save(function (err) {
if (err) {
res.status(400).send({
message: 'order couldn\'t placed.'
});
} else {
async.waterfall([
myFirstFunction,
mySecondFunction,
myThirdFunction,
myLastFunction,
], function (err) {
if (err) {
return next(err);
}
});
}
});
//---------------------------test function async.waterflow --------------------------//
function myFirstFunction(done) {
// Generate random token
crypto.randomBytes(20, function (err, buffer) {
var token = buffer.toString('hex');
return done(err, token);
});
}
function mySecondFunction(token, done, err) {
// Lookup user by username
return done(err, token);
}
function myThirdFunction(token, done) {
// If valid email, send reset email using service
var httpTransport = 'http://';
if (_environment2.default.secure && _environment2.default.secure.ssl === true) {
httpTransport = 'https://';
}
res.render(path.resolve('server/components/orderStatus/orderrequested'), {
email: req.user.email,
name: req.user.name,
appName: 'Restaurant App'
}, function (err, emailHTML) {
return done(err, emailHTML);
});
}
function myLastFunction(emailHTML, done) {
var mailOptions = {
to: req.user.email,
from: 'info@impnolife.org',
subject: 'Thank you for your order.',
html: emailHTML
};
mailgun.messages().send(mailOptions, function (err) {
if (!err) {
res.json(order);
} else {
return res.status(400).send({
message: 'Failure sending email'
});
}
});
}
//---------------------------test function async.waterflow END--------------------------//
}