从嵌套函数回来

我是新的节点/ JavaScript,所以我的问题可能是微不足道的,但它造成我的麻烦不下。

我有以下代码。 它成功地检查了UnitOwner值的数据库。 问题是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); } }); } };