2013-05-08 2 views
0

Обновление: Решено, это действительно проблема с областью. Я обошел его, переместив код пользовательского списка внутри класса базы данных и вернув предварительно настроенный список.переменная пустая при выполнении асинхронного вызова в node.js (закрытие)

Используя node.js, я делаю асинхронный вызов функции findUser, и я создаю список пользователей из обратного вызова в содержимое переменной. Это работает отлично во время цикла (где он говорит, что переменная содержимого доступна), но когда цикл выходит, переменная пуста. Как я могу переписать код так, чтобы значение переменной содержимого было доступно вне цикла?

exports.listUsers=function(req,res) { 
    var content='' 
    isLoggedIn=user.findUser({},function(myuser) { 
     content = content +'<li>' + myuser.firstname + ' ' + myuser.lastname + "</li>\n"; 
      //here value of content var is available 
      console.log(content) 
    }) 
     //here value of content var is empty 
    console.log(content) 
    showPage(req,res,{'content':content}) 
} 
+0

возможно ли, что это проблема обзорной? Не могли бы вы ссылаться на живую версию или попытаться построить jsfiddle? Я сделал это, но ничего не нашел. – maaachine

+1

Конечно, он пуст, обратный вызов выполняется ** асинхронно **. Разве ты не сказал это сам? Или вы не понимали, что это значит? – Bergi

ответ

2

Если findUser() асинхронный (который вы укажете), то проблема в том, что findUser() еще не завершена, когда showPage() называется.

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

Я не знаю точно, что вы пытаетесь достичь, но это общий шаблон дизайна вам нужно будет использовать:

exports.listUsers=function(req,res) { 
    isLoggedIn=user.findUser({},function(myuser) { 
     var content = '<li>' + myuser.firstname + ' ' + myuser.lastname + "</li>\n"; 
     //here value of content var is available 
     console.log(content) 
     showPage(req,res,{'content':content}) 
    }); 
} 

Или, если обратного вызова вызывается много раз один раз каждый пользователь, вы можете накапливать контент и вызвать showPage() на последнюю функцию обратного вызова:

exports.listUsers=function(req,res) { 
    var content = ""; 
    isLoggedIn=user.findUser({},function(myuser) { 
     content += '<li>' + myuser.firstname + ' ' + myuser.lastname + "</li>\n"; 
     //here value of content var is available 
     console.log(content) 
     // devise some logic to know when the last callback is being called 
     // perhaps based on a user count 
     if (this is the last user callback) { 
      showPage(req,res,{'content':content}) 
     } 
    }); 
} 
+0

Это не сработало бы в моем случае, потому что анонимная функция была бы вызвана один раз для каждого пользователя: функция showPage была бы вызвана несколько раз каждым циклом, возвращающим пользователей в то время. Вместо обратного вызова я упростил и вернул только готовый список - спасибо –

+0

@YounElan - тогда вам нужно будет накапливать контент, как вы делали, но знаете, когда обратный вызов вызывается в последний раз и вызывается ' showPage() 'then. Я добавил пример моего ответа. – jfriend00

Смежные вопросы