Node.js返回,callback和源代码执行stream程 – 运行时

我对node.js的工作方式感到困惑,我正在谈论callback,返回以及源代码的执行方式。

我使用的是sails.js,但我不认为它是链接的,我认为这更多的是JS的工作方式。

源代码:

module.exports = function (req, res, callback) { if (req.session.authenticated) { // Accept user authentication. return callback(); } else { // Not authenticated. Try auto authentication. if(validator.check([validator.rulesHardwareId(req.param('hardwareId'))])){ Device.findOne({hardwareId: req.param('hardwareId')}, function(err, device){ if(err){ return res.json({message: "You are not permitted to perform this action. You have to connect to the platform before. [Wrong hardwareId or DB error]", data: {err: err}, status: false}, 403); } if(device){ // Connect the device. req.session.authenticated = true; req.session.from = 'device'; // Search for the device's owner. User.findOne({id: device.userId}, function(err, user){ if(err){ return res.json({message: "DB error.", data: {err: err}, status: false}, 403); } if(user){ // Add data about the user. req.session.user = user; return callback(); }else{ return res.json({message: "Device found but device's owner doesn't found.", data: {err: err}, status: false}, 403); } }); }else{ return res.json({message: "You are not permitted to perform this action. You have to connect to the platform before. [Wrong hardwareId]", data: {err: err}, status: false}, 403); } }); } return res.json({message: "You are not permitted to perform this action. You have to connect to the platform before. [Give hardwareId ?]", data: {}, status: false}, 403); } }; 

代码不是那么重要,关键是我收到了这个消息:“你不能执行这个动作,你必须先连接到这个平台上(给硬件ID?

但行动是创造。 好的,所以我调用callback函数()并返回它,但源代码继续? 并执行最后一行? 为什么? 我不明白这一点。 如果我把最后一行放在ELSE中,我会收到消息“The action is created”。

如果有人能解释我..我认为join返回关键字是有用的,以防止这一点,但它看起来像我错了。

谢谢。

当你像你的代码一样进行asynchronous请求时,执行stream程不会等待响应。 它只是继续,似乎没有什么可以阻止它(因为那里什么都没有)。 所以你的主函数立即返回。

你提供的嵌套return语句是为这些嵌套函数的调用者返回一个值。 那么来电者是谁? 那么,你将这些函数作为parameter passing给一些内部代码,所以内部代码就是调用者,而内部代码可能不关心return值。

所以这意味着所有这些return语句都是毫无用处的,因为你的主函数已经返回了,调用你的函数的代码忽略了它们。

所以你会怎么做? 那么,你可以看到,你正在接收一个callback函数,传递给你的module.exports函数。 所以你应该做的是将你通常return的数据作为parameter passing给callback函数。 然后,无论函数传递的callback将接收该数据,并做任何你想要的。

 module.exports = function (req, res, callback) { if (req.session.authenticated) { // Accept user authentication. callback(); } else { // Not authenticated. Try auto authentication. if(validator.check([validator.rulesHardwareId(req.param('hardwareId'))])){ Device.findOne({hardwareId: req.param('hardwareId')}, function(err, device){ if (err) { callback(res.json({message: "You are not permitted to perform this action. You have to connect to the platform before. [Wrong hardwareId or DB error]", data: {err: err}, status: false}, 403)); } else if (device) { // Connect the device. req.session.authenticated = true; req.session.from = 'device'; // Search for the device's owner. User.findOne({id: device.userId}, function(err, user){ if (err) { callback(res.json({message: "DB error.", data: {err: err}, status: false}, 403)); } else if (user) { // Add data about the user. req.session.user = user; callback(); } else { callback(res.json({message: "Device found but device's owner doesn't found.", data: {err: err}, status: false}, 403)); } }); } else { callback(res.json({message: "You are not permitted to perform this action. You have to connect to the platform before. [Wrong hardwareId]", data: {err: err}, status: false}, 403)); } }); } else { callback(res.json({message: "You are not permitted to perform this action. You have to connect to the platform before. [Give hardwareId ?]", data: {}, status: false}, 403)); } } }; 

所以你的函数会被调用如下所示:

  // This is the callback ------v my_module(the_req, the_res, function(err) { if (err) { // do something with the error console.log(err); } }); 

这可能不是你的问题的直接答案。 但我相信,这将有助于其他人。


考虑以下情况:

情况1:没有使用返回,function是asynchronous的。

 (function caller(){ var returnedValue; /* Following cannot be the case returnedValue = callee("TestParam"); */ calleeWithoutReturn("TestParam", function(returnFromCallback){ console.log(returnFromCallback); }); })()//() is to init the function function calleeWithoutReturn(params, callback){ console.log("Received Param value", params); callback("Return Value Here"); /* Here the callback is actually the function which get passed over here. You can actually call/execute it as many times as you want and it does that. Following is the sample code */ for (i = 0; i < 5; i++) { callback("Return Value Here " + i); } } 

情况2:使用返回的地方,function仍然是asynchronous的

 (function caller(){ var returnedValue; /* Following cannot be the case returnedValue = callee("TestParam"); */ calleeWithReturn("TestParam", function(returnFromCallback){ console.log(returnFromCallback); }); })()//() is to init the function function calleeWithReturn(params, callback){ console.log("Received Param value", params); //Try adding return here as well. It stops executing next statements and control exits. callback("Return Value Here"); /* Here the callback is actually the function which get passed over here. You can actually call/execute it as many times as you want and it does that. Following is the sample code */ for (i = 0; i < 5; i++) { return callback("Return Value Here " + i); //When return executed it exits from the for loop & this functino function. } } 

情况3:使用返回和function同步。

 (function caller(){ var returnedValue; returnedValue = calleeWithReturn("TestParam"); console.log("caller received the return value:", returnedValue); })()//() is to init the function function calleeWithReturn(params){ console.log("Received Param value", params); return "Params returned from callee function " + params } 

情况4:不使用返回和function同步。

 (function caller(){ var returnedValue; returnedValue = calleeWithReturn("TestParam"); console.log("caller received the return value:", returnedValue); //Undefined if you dont return any value. })()//() is to init the function function calleeWithReturn(params){ console.log("Received Param value", params); //If you dont return the function always returns 'Undefined' //return "Params returned from callee function " + params } 

希望现在可以让你在不同的情况下返回实际使用情况。