如何使用asynchronous瀑布的JavaScriptcallback工作

我目前正在通过一个教程来实现从node.js应用程序的密码重置,并要求我使用库asynchronous来清理代码从callback混乱。 我对JavaScript比较陌生,来自Java和Objective-C等更强大的types语言,我遇到了一些难题,以解决语言中固有的自由问题。

无论如何,我明白每个前面的函数是如何通过callback函数将值传递给下一个函数的,但是在每个callback函数开始时,我都无法理解“err”参数。 例如,在第一个函数中,引发的callback被完成(err,token),然而下一个函数将token作为其第一个参数,而不是err。 我正在努力弄清楚下一个函数如何得到这个标记参数,并在“err”参数是callback中列出的参数时使用它。 我可能会误解这个概念或错过了一些东西,所以任何帮助都是值得赞赏的。

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接受两个参数:任务列表和callback。

done不是简单的列表中的下一个任务。 这是async.waterfall知道如何进行的一些具体function。 把它想成是

 function done(err, result) { if (err) { callback(err); } else { tasks[i++](result, done); } } 

(如果done只接受两个参数)

即只有结果被传递给列表中的下一个任务。 如果错误通过,则调用callback。

相关的源代码 (这可能不是那么容易理解)。