2013-06-05 4 views
0

Так же, как я думал, что я понял, объем JS ...Javascript Асинхронный Возвращаемое значение

Возьмите этот код:

function init() { 

    var page; 
    var pageName = $('body').data('page'); 

    switch(pageName) { 

     // (there are more switch cases here normally...)     

     case 'pSearchLatest': 
      require(['searchresults'], function (SearchResults) { 
       page = new SearchResults().init(); 
       console.log(page); // <- shows the object! 
      }); 

     default: 
      break; 

    } 

    console.log(page); // <- undefined 
    return page; 

} 

Смотрите комментарии журнала консоли. Почему второе возвращается undefined, когда var page объявлен вне сферы действия оператора switch?

EDIT

Так что я ошибочно думал, что это был вопрос, но сфера его вплоть до асинхронной природы AMD.

Как я могу вернуть значение страницы в области require тем же методом без проверки цикла while для неопределенного?

EDIT 2

Я сделал это так:

function init(callback) { 

    case 'pSearchLatest': 
     require(['searchresults'], function (SearchResults) { 
      page = new SearchResults().init(); 
      callback(page) 
     }); 
} 

и в моей странице, которая вызывает метод оберточная инициализации():

new PageController().init(function(asyncViewController) { 
    App.view = asyncViewController; 
}); 
+2

Дубликат [Как вернуть ответ от вызова AJAX?] (Http://stackoverflow.com/q/14220321/710446) - прочитайте, что чрезвычайно полезно Q & A. Проблема не является проблемой с точки зрения объема, это вопрос времени. Обратный вызов имеет * еще не запущенный *, когда выполняется нижний «журнал». Обратный вызов 'require' работает ** последний **, * после того, как *' init' завершился. – apsillers

+0

Что вы ожидаете от него? – j08691

+1

Требуется вызов async – UpTheCreek

ответ

3

Вы правильно поняли область. Код в этой внутренней функции действительно присваивает переменной во внешней области.

Что вы не понимаете, это асинхронное поведение. Функция require принимает функцию обратного вызова, которая будет вызвана в будущем - когда запрошенный модуль будет доступен. Тем не менее, он немедленно возвращает и поток управления приведет к оператору console.log, который печатает undefined - который является значением, которое page имеет в то время.

Вы должны быть в состоянии признать, что, поскольку undefined регистрируется первого и утверждение журнала в функции обратного вызова (с объектом) выполняет позже, даже если речь идет выше в коде.

+0

Ах, конечно! Определение ASYNCHRONOUS модуля. Duh. Спасибо, примет за 9 минут: D. –

+0

eurgh, как вернуть страницу в этот метод init? Думаю, я мог бы сделать какое-то время (страница == undefined), но это отвратительно? –

+1

@AdamWaite Дать 'init()' обратный вызов ... – canon

1

Два возможных причин .. вы не соответствовали делу. или обратный вызов, когда значение присвоения значения page еще не выполнено. Я предполагаю, что это последнее, потому что это было бы легко увидеть, если вы свалили case. Просмотрите документацию для любой используемой вами библиотеки AMD и посмотрите, как выполняется выполнение функций (функций), переданных в require.

Также, как правило, старайтесь избегать возврата значений, определяемых асинхронными вызовами, подобными этому. Вместо этого используйте какой-то шаблон Observer для подписки на конкретное событие, которое может запускаться из разных мест.

2

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

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