Node.js SailsJS使用一个控制器操作调用两个服务方法

Node.js SailsJS使用一个控制器操作调用两个服务方法,node.js,express,sails.js,Node.js,Express,Sails.js,我对学习完整堆栈开发相当陌生,特别是后端方面的东西,我正在尝试弄清楚异步Nodejs的东西 在提交忘记密码表单后,我需要完成一些后端操作。控制器的动作基本上是这样的(我知道这样做肯定是错误的): 每项服务都会帮助发送密码重置电子邮件 saveResetPasswordValues: function (token, userEmail, cb) { var expiration = Date.now() + 3600000; // 1 hour User.update({ ema

我对学习完整堆栈开发相当陌生,特别是后端方面的东西,我正在尝试弄清楚异步Nodejs的东西

在提交忘记密码表单后,我需要完成一些后端操作。控制器的动作基本上是这样的(我知道这样做肯定是错误的):

每项服务都会帮助发送密码重置电子邮件

saveResetPasswordValues: function (token, userEmail, cb) {
    var expiration = Date.now() + 3600000; // 1 hour
    User.update({ email: userEmail },
        { resetPasswordToken: token,
            resetPasswordExpires: expiration})
        .exec(function (err, user) {
            if (err) { return cb({ status: 404, message: 'Could not find user with that email address' }); }
            return cb(err, user);
        });
},

sendForgotPasswordEmail: function (token, userEmail, host, cb) {
    var htmlMessage =
        '<h4>You are receiving this because you (or someone else) have requested the reset of the password for your account.</h4>' +
        '<p>Please click on the following link, or paste this into your browser to complete the process:</p>' +
        "<p><a href='http://" + host + '/reset/' + token + "'> Link to password reset </a></p>" +
        '<p>If you did not request this, please ignore this email and your password will remain unchanged.</p>';

    var emailInfo = {
        to: userEmail,
        from: "customerservice@smallchangeproj.com",
        subject: "Small Change Project Password Reset",
        message: htmlMessage,
        fromName: "Small Change Project"
    };

    .... some code for sending the email ...

     return cb(null, 'email has been sent');

}

正确的方法是什么?我仍然想将逻辑分为两种服务方法…

正如错误消息已经建议的那样,在已经发送响应后,不允许向浏览器发送另一个响应,因为在网页请求的经典请求-响应周期中,浏览器只接受每个请求的一个响应

您必须将第二个服务函数的调用放入第一个服务函数的回调中,并在组合对象中发送服务帮助程序的结果,例如:

    forgot: function (req, res) {
        var token = "febfoebfoui38383303cnc";
        var userEmail = req.body.email;
        var host = req.headers.host;

        AuthService.saveResetPasswordValues(token, userEmail, function (err, savedRecord) {
            if (err) { return res.send(404, '\n\nerror occurred\n\n'); }

            AuthService.sendForgotPasswordEmail(token, userEmail, host, function (err, message) {
                if (err) { return res.send(404, '\n\nerror occurred\n\n'); }
                // make sure to adapt your client logic for this response
                return res.json({savedRecord: savedRecord, message: message);
            });
        });
    },
异步回调的一般结论是,如果函数调用依赖于前一个调用的结果,则必须将第二个调用始终嵌套到前一个调用的回调中,以便以正确的顺序调用它们,第二个调用可以访问第一个调用的结果

如果希望在一个响应中发送多个异步函数的结果,只需嵌套函数调用,这样就可以在最终回调中访问所有结果

error: Sending 500 ("Server Error") response: 
 Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:690:11)
    at ServerResponse.res.setHeader (/usr/lib/node_modules/sails/node_modules/express/node_modules/connect/lib/patch.js:133:22)
    at ServerResponse.res.set.res.header (/home/zacharyhustles/smallChangeAPI/node_modules/sails/node_modules/express/lib/response.js:577:10)
    at ServerResponse.res.send (/home/zacharyhustles/smallChangeAPI/node_modules/sails/node_modules/express/lib/response.js:142:12)
    at ServerResponse.res.json (/home/zacharyhustles/smallChangeAPI/node_modules/sails/node_modules/express/lib/response.js:223:15)
    at /home/zacharyhustles/smallChangeAPI/api/controllers/UserController.js:123:15
    at /home/zacharyhustles/smallChangeAPI/api/services/AuthService.js:50:4
    at Object.module.exports.simpleSendEmail (/home/zacharyhustles/smallChangeAPI/api/services/EmailService.js:48:12)
    at Object.bound [as simpleSendEmail] (/home/zacharyhustles/smallChangeAPI/node_modules/lodash/dist/lodash.js:729:21)
    at Object.module.exports.sendForgotPasswordEmail (/home/zacharyhustles/smallChangeAPI/api/services/AuthService.js:46:16)
    at Object.bound [as sendForgotPasswordEmail] (/home/zacharyhustles/smallChangeAPI/node_modules/lodash/dist/lodash.js:729:21)
    at Object.module.exports.forgot (/home/zacharyhustles/smallChangeAPI/api/controllers/UserController.js:121:15)
    at bound (/home/zacharyhustles/smallChangeAPI/node_modules/lodash/dist/lodash.js:729:21)
    at routeTargetFnWrapper (/home/zacharyhustles/smallChangeAPI/node_modules/sails/lib/router/bind.js:179:5)
    at callbacks (/home/zacharyhustles/smallChangeAPI/node_modules/sails/node_modules/express/lib/router/index.js:164:37)
    at param (/home/zacharyhustles/smallChangeAPI/node_modules/sails/node_modules/express/lib/router/index.js:138:11) [Error: Can't set headers after they are sent.]
    forgot: function (req, res) {
        var token = "febfoebfoui38383303cnc";
        var userEmail = req.body.email;
        var host = req.headers.host;

        AuthService.saveResetPasswordValues(token, userEmail, function (err, savedRecord) {
            if (err) { return res.send(404, '\n\nerror occurred\n\n'); }

            AuthService.sendForgotPasswordEmail(token, userEmail, host, function (err, message) {
                if (err) { return res.send(404, '\n\nerror occurred\n\n'); }
                // make sure to adapt your client logic for this response
                return res.json({savedRecord: savedRecord, message: message);
            });
        });
    },