2016-07-17 76 views
1

我是新来的节点/ 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); 

     }); 

    } 
}; 
+2

[为什么我的变量在函数内部修改后没有改变? - 异步代码引用](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) –

回答

1

代码中有几个问题。

首先,假设if (err)条款不具有相同的return reply(output)声明,这意味着你的代码将永远做return(output)不管什么为Unit.findById是异步的。也就是说,代码不会等待Unit.findById的响应完成,只要它调用该代码,代码将继续并最终触及return声明。

其次,Owner.findOne应该在回调函数的代码块中拥有自己的return语句,因为代码只会在其中传播。

因此,对于Owner.findOne和Unit.findById成功执行的快乐路径情况,您仍然会收到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); 
    } 

});

+0

工作。谢谢! – gearhead

0

Owner.findOne是另一种异步功能,所以你需要移动reply(output)到您拥有output.success = false; else块和Owner.findOne的回调中添加其他reply(output)电话。

在您的代码return reply(output)被称为之前异步回调Owner.findOne执行。此外,您不需要return,因为您无法使用return从这些回调中返回值,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); 
     } 
    }); 
    } 
};