2016-07-17 3 views
1

Я новичок в 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); 

     }); 

    } 
}; 
+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; и добавить еще один вызов reply(output) в обратном вызове Owner.findOne.

В коде 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); 
     } 
    }); 
    } 
}; 
Смежные вопросы