GAE/Angular 应用程序中的 window.init() 无限循环
2015-02-26
761
我正在使用带有 AngularJS 的 cloud enpoints 演示,并且我遇到了他们建议的在加载 client.js 后运行授权的方法的无限循环。这是建议的方法。
首先,在所有其他脚本标记之后(对于 Angular 和其他 JS 文件,我正在这样做):
<script>
function init() {
window.init();
}
</script>
<script src="https://apis.google.com/js/client.js?onload=init"></script>
然后,在控制器中,我处理窗口初始化,如下所示:
$window.init = function () {
// Loads the OAuth and helloworld APIs asynchronously, and triggers login
// when they have completed.
var apisToLoad;
var callback = function () {
if (--apisToLoad == 0) {
googleAPI.signin(true,
googleAPI.userAuthed);
appContext.appReady = true;
alert('loaded');
}
}
apisToLoad = 2; // must match number of calls to gapi.client.load()
gapi.client.load('helloworld', 'v1', callback, googleAPI.apiRoot);
gapi.client.load('oauth2', 'v2', callback);
};
我认为我发现的是这里有一个竞争条件,其中 $window.init 没有足够早地设置,所以我最终收到以下消息:
Uncaught RangeError: Maximum call stack size exceeded
这是因为“window.init()”只是回调到 init() 函数并超出了堆栈。
关于如何更好地处理这个问题有什么建议吗?谢谢。
3个回答
第一行在那里创建了一个无限循环,因为您在实际的 window.init 中调用了 window.init。
<script>
/**
* Initializes the Google API JavaScript client. Bootstrap the angular module after loading the Google libraries
* so that Google JavaScript library ready in the angular modules.
*/
function init() {
gapi.client.load('conference', 'v1', null, '//' + window.location.host + '/_ah/api');
gapi.client.load('oauth2', 'v2', callback);
};
</script>
<script src="//apis.google.com/js/client:plusone.js?onload=init"></script>
您可以尝试此代码以查看是否对您更有意义
Albertoimpl
2015-02-26
看起来您的角度控制器没有及时加载/执行,无法找出原因,但您可以等待文档准备好,以真正的 jQuery 方式:
function init() {
angular.element(document).ready(function() {
window.init();
});
}
到那时 Angular 应该已经完成​​加载了。
Jaime Gomez
2015-02-26
通过这样做,您告诉 window.init 调用自身,从而创建一个无限循环。
<script>
function init() {
window.init();
}
init===window.init; // => true
</script>
<script src="https://apis.google.com/js/client.js?onload=init"></script>
如果您仔细查看 我的代码 ,您会发现我以不同的方式命名了这些函数,如下所示:
<script>
function init() {
window.initGapi();
}
init===window.initGapi; // => false
</script>
<script src="https://apis.google.com/js/client.js?onload=init"></script>
然后只需在您的控制器中定义
initGapi
即可:
$window.initGapi = function () {}
对已接受答案的注释中的代码会等到 api 加载后才启动应用程序,这需要更长的时间。
willlma
2015-06-03