从嵌套函数回来
我是新的节点/ JavaScript,所以我的问题可能是微不足道的,但它造成我的麻烦不下。
我有以下代码。 它成功地检查了Unit
和Owner
值的数据库。 问题是if语句后面的代码else if (Owner){
按预期执行,但是,在程序永远不会到达return reply(output);
线,我期望它应该。
我认为它是我从Owner.findOne(...
代码。
任何人都可以看到我做错了什么?
exports.sale = { tags: ['api'], validate : { //blah blah blah }, handler : function(request, reply) { var output = { success: true, operations: [], epoch: Date.now() }; Unit.findById(request.payload.deviceNumber, function(err, device) { if (err) { //blah blah blah } if (device) { Owner.findOne({OwnerId: device.Owner}, function(err, Owner) { if (err) { //blah blah blah } else if (Owner){ //make changes to output.operations } }); } else { output.success = false; } return reply(output); }); } };
代码中有几个问题。
首先,假设if (err)
子句不具有相同的return reply(output)
语句,这意味着无论Unit.findById
是asynchronous的,您的代码将始终执行return(output)
。 也就是说,代码不会等待来自Unit.findById
的响应完成,只要它调用它,代码将继续前进,并最终击中return
语句。
其次, Owner.findOne
应该在callback函数的代码块中有自己的return
语句,因为代码只能在其中传播。
因此,对于Owner.findOne和Unit.findById成功执行的快乐path情况,您仍然会收到output.success = false
的响应。
所以,忽略代码的可读性,要解决这个问题 – 你的代码应该看起来像这样。
Unit.findById(request.payload.deviceNumber, function(err, device) { if (err) { //blah blah blah output.success = false; return reply(output); } if (device) { Owner.findOne({OwnerId: device.Owner}, function(err, Owner) { if (err) { //blah blah blah output.success = false; return reply(output); } else if (Owner){ //make changes to output.operations } output.success = true; return reply(output); }); } else { output.success = false; return reply(output); }
});
Owner.findOne
是另一个asynchronous函数,因此您需要将reply(output)
移动到您有output.success = false;
的else块output.success = false;
并在Owner.findOne
的callback中添加另一个reply(output)
调用。
在您的代码中,在执行Owner.findOne
的asynchronouscallback之前调用return reply(output)
。 另外你不需要return
,因为你不能使用return
值从这些callback中返回一个值,所以return
只能退出函数。
exports.sale = { tags: ['api'], validate: { //blah blah blah }, handler: function(request, reply) { var output = { success: true, operations: [], epoch: Date.now() }; Unit.findById(request.payload.deviceNumber, function(err, device) { if (err) { //blah blah blah } if (device) { Owner.findOne({ OwnerId: device.Owner }, function(err, Owner) { if (err) { //blah blah blah } else if (Owner) { //make changes to output.operations } reply(output); }); } else { output.success = false; reply(output); } }); } };