我目前正在通过一个教程来实现从 node.js 应用程序重置密码,并且我需要使用库异步来清理代码,使其免于回调困惑。我是 Javascript 的新手,来自 Java 和 Objective-C 等强类型语言,我在掌握语言固有的自由方面遇到了问题。
无论如何,我了解每个前面的函数本质上是如何通过回调将值向下传递给下一个函数的,但是我无法理解每个回调调用开始时“err”参数的意义。例如,在第一个函数中,调用的回调是 done(err, token),而下一个函数的第一个参数是 token 而不是 err。我正在努力弄清楚下一个函数如何获取该 token 参数并在“err”参数是回调中列出的参数时使用它。我可能误解了这个概念或遗漏了某些东西,因此我们将不胜感激。
app.post('/forgot', function (req, res, next) {
async.waterfall([function (done) {
crypto.randomBytes(20, function (err, buf) {
var token = buf.toString('hex');
done(err, token);
});
},
function (token, done) {
User.findOne({ email: req.body.email }, function (err, user) {
if (!user) {
return { error : 'No account with that email address exists'};
}
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; //1 hour
user.save(function (err) {
done(err, token, user);
});
});
},
function (token, user, done) {
var smtpTransport = nodemailer.createTransport('SMTP', {
service: 'SendGrid',
auth : {
user: "swagboi",
pass: "woo"
}
});
var mailOptions = {
to: user.email,
from: 'passwordreset@demo.com',
text: 'You are receiving this because you (or someone else) have requested hte reset of the password for your account. \n\n' +
'Pleaes click on the following link, or paste this into your browser to complete the process: \n\n' +
'http://' + req.headers.host + '/reset/' + token + '\n\n' +
'If you did not request this, please ignore this email and your password will remain unchanged. \n'
};
smtpTransport.sendMail(mailOptions, function (err) {
done(err, 'done');
});
}
], function (err) {
if (err) return next(err);
})
});
最佳答案
如果仔细观察,您会发现 async.waterfall
接受两个参数:任务列表和回调。
done
不仅仅是列表中的下一个任务。它是一些特定的函数,async.waterfall
知道如何继续。把它想象成
function done(err, result) {
if (err) {
callback(err);
} else {
tasks[i++](result, done);
}
}
(如果 done
只接受两个参数)
即只有结果会传递给列表中的下一个任务。如果错误通过,则会调用回调。
Relevant source code (这可能不是那么容易理解)。
关于javascript - 回调如何在带有异步 waterfall 的 Javascript 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34885644/