2016-07-17 5 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)文を持っていないと仮定すると、これはあなたのコードは、常に関係なくUnit.findByIdとしては非同期で何return(output)を行うことを意味します。つまり、コードはUnit.findByIdの応答が終了するのを待つことはなく、コードを呼び出すとすぐに、コードは移動して最終的にreturnステートメントに当ります。

第2に、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別の非同期機能であるので、あなたは、あなたがoutput.success = false;を持っているとOwner.findOneのコールバック内の別のreply(output)呼び出しを追加し、他のブロックに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); 
     } 
    }); 
    } 
}; 
関連する問題