正如我认为我了解JS的作用域…
用下面的代码:
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语句的范围之外声明的?
编辑
所以我错误地认为这是一个作用域问题,但这是由于AMD的异步特性。
我如何在同一方法的require作用域中返回page的值而没有while循环检查未定义?
编辑2
我是这样做的:
function init(callback) {
case 'pSearchLatest':
require(['searchresults'], function (SearchResults) {
page = new SearchResults().init();
callback(page)
});
}
和在我的页面中调用封装init()方法:
new PageController().init(function(asyncViewController) {
App.view = asyncViewController;
});
您确实正确理解了作用域。内部函数中的代码确实给外部作用域中的变量赋值。
你不理解的是异步行为。require
函数接受一个回调函数,该函数将在将来的某个时候被调用-当所请求的模块可用时。然而,它确实立即返回,控制流将导致console.log
语句,它打印undefined
-这是page
变量在时的值。
您应该能够认识到,因为undefined
首先记录,并且回调中的日志语句(与对象一起)稍后执行,即使它在代码中出现在上面。
require
是异步的,因此您的函数首先退出,然后处理回调函数。
两个可能的原因…你和箱子不匹配。或者给page
赋值的回调函数还没有执行。我猜是后者,因为如果你的case
失败了,它会很明显。查看你使用的任何AMD库的文档,看看传递给require
的函数是如何执行的。
作为一般规则,尽量避免返回由这样的异步调用确定的值。而是使用某种观察者模式来订阅可以从不同位置触发的特定事件。