2015-08-25 2 views
0
router.get('/xyz', function(req, res, next) { 
    var myObj; 

    XX.getXXByUsername("ee", function(err, doc){ 
    console.log("A: " + doc); //executes second, doc is object that I want 

    myObj = doc; 

    }); 

    console.log("B: "+ " " + myObj); //executes first, myObj = undefined 

    res.render("pr", {title: "XX", myObj: myObj}); 
}); 

В основном, я делаю это, потому что хочу отправить объект в шаблон нефрита. Я могу получить объект в консоли A, но в консоли B myObj не определен. Я предполагаю, что это потому, что консоль B выполняется до getXXbyUsername, потому что в getXXbyUsername callback я определяю myObj.Почему B выполняется до A в узле?

Я не знаю, объяснил ли я, в чем моя проблема, но я начинаю, и это лучшее объяснение проблемы, которую я могу дать.

+6

Это дубликат [вопрос канонического асинхронного ответа] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call). – ssube

ответ

2

Узел js выполняет асинхронный код. В случае извлечения кода, если узел сталкивается с задачей, для выполнения которой требуется некоторое время, перед выполнением этой задачи он переходит к следующей строке кода. Этот шаблон отличается от таких языков, как PHP. В вашем коде XX.getXXByUsername - это операция с базой данных, которая требует много времени. Поэтому до завершения операции с базой данных он переходит к console.log("B: "+ " " + myObj); и, следовательно, muObj не определен. Одним из способов решения этой проблемы является использование функций обратного вызова. В узле js для каждой функции обратный вызов передается как аргументом, а обратный вызов принимает объект ошибки в качестве первого параметра и результат основной функции в качестве следующего аргумента. В вашем случае, doc. Обратный вызов выполняется только после завершения выполнения функции . Итак, в console.log("A: " + doc), doc является результатом функции XX.getXXByUsername и, следовательно, не является неопределенным.

+1

Вы также можете использовать библиотеки, такие как async, которые могут содержать асинхронные функции, чтобы убедиться, что функции вызываются в том порядке, в котором вы хотите. – ace040686

0

Поскольку обратный вызов в getXXByUsername() выполняется позже кода, следующего за этим вызовом функции. Другими словами, обратный вызов выполняется после того, как ваша функция извлекает данные (из базы данных?). Между тем основная функция продолжает выполнение, поэтому вы получаете B раньше, чем A.