我从一个演示程序离子(开始ionic start myApp sidemenu),并添加一个resolve到一个视图:
ionic start myApp sidemenu
resolve
resolve: { issue: function($q, $timeout) { var defer = $q.defer(); //defer.reject(); // Doesn't work browser or device $timeout(defer.reject); // Works in browser, but not device return defer.promise; } }
我resolve在这里监视被拒绝的s:
.run(function($ionicPlatform, $rootScope, $ionicLoading) { $ionicPlatform.ready(function() { // regular stuff here $rootScope.$on('$stateChangeError', function() { $ionicLoading.show({ template: 'All good!' }); }); }); });
由于某种原因,如果resolve立即拒绝(请参见defer.reject()上文),$stateChangeError则不会运行的回调。如果我做的完全一样,但是在Ionic之外,那行得通!
defer.reject()
$stateChangeError
而且,尝试resolve通过这样做来延迟拒绝会$timeout(defer.reject);导致不同的行为。现在,它可以按预期在浏览器中运行,但仍无法在设备上运行。尝试进一步延迟,将导致设备成功:
$timeout(defer.reject);
$timeout(function() { defer.reject(); }, 250); // Doesn't work for me with 200 or less
谁能阐明这一点?
[**SEE HERE HOW TO REPRODUCE THE ISSUE**](https://github.com/moroshko/ResolveIssue)
根据我对Angular和Promise模型的经验。为了解决/拒绝承诺,Angular必须在JS事件循环的一个周期(nextTick)上打钩,这可以使用$ scope.apply()来完成,这是我们在单元测试中模拟此类事情的方式。
这是一篇很棒的文章,谈论$ timeout和$ scope。$ evalAsync-从我可以收集到的信息中,$ timeout正在下一滴答中评估函数。这就是该代码按您概述的方式工作的原因。
resolve: { issue: function($q, $timeout) { var defer = $q.defer(); //defer.reject(); // <---- no nextTick $timeout(defer.reject); // <---- $timeout evaluates on nextTick return defer.promise; } }
这是另一篇谈论$ q的textTick实现的文章。
我知道这不能解决您的问题-但应该可以弄清为什么会发生这种情况!祝好运!