2016-07-17 74 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); 
     } 
    }); 
    } 
};