从嵌套函数返回

Coming back from nested functions

本文关键字:返回 函数 嵌套      更新时间:2023-09-26

我是node/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是异步的,您的代码都将始终执行return(output)。也就是说,代码不会等待来自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); 
   }

});

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);
      }
    });
  }
};