javascript - 回调如何在带有异步 waterfall 的 Javascript 中工作

标签 javascript node.js

我目前正在通过一个教程来实现从 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/

相关文章:

javascript - 小数验证允许通过 Javascript 在按键事件上小数点后保留两位数字

javascript - Greasemonkey - 图像不显示

javascript - 通过单击按钮和带有 jQ​​uery 的单独 JS 文件,在 Google map 标记上触发单击事件

javascript - 打开一个 DIVS 时关闭所有其他 DIVS

node.js - 如何在Elastic Search中编写条件

javascript - 在 node.js 中验证一个集合是否为空

javascript - 为什么这个数组中的值(显然)立即改变

javascript - 使用 javascript 使用react.js 更改 html

javascript - Express中间件意味着请求超时

javascript - 如何将此 node.js 模块降级到特定版本并防止以后自动升级?