我正在尝试使用$q
服务来解决使用AngularUI路由器的$q.all()
函数的多个承诺,但由于某些原因,这会失败或者无法按预期工作。
这是我的配置文件的一部分,其中包含$stateProvider
:
.state('home.team',
{
url : '^/team',
views : {
'main' : {
templateUrl : ConfigProvider.path.views + '/segment/home/team.html',
controller : 'SegmentHomeTeamCtrl',
resolve : {
promiseData : function(ResolveService) { return ResolveService.resolveHomeTeam(); }
}
},
'subMenu' : {
templateUrl : ConfigProvider.path.views + '/menu/home/team.html'
}
}
});
这是位于resolveHomeTeam
服务中的Resolve
函数:
function resolveHomeTeam()
{
var promises = [];
promises.push($q.defer());
UserService.team('me', function(data)
{
promises[0].resolve(data);
}, function()
{
promises[0].reject();
});
return $q.all(promises);
}
正如你在这种情况下所看到的那样,我只是将一个诺言推入数组中,我确信它已经被解决了。
由于唯一的承诺已经解决,$q.all()
返回的承诺是否也应该得到解决?不应该将promiseData
数据注入SegmentHomeTeamCtrl
控制器吗?
如果我尝试在promiseData
控制器内输出SegmentHomeTeamCtrl
,我会得到整个承诺,包含服务器购买返回的实际数据,原因是我无法访问它。
答案 0 :(得分:2)
您几乎正在做的事情正确:您正在返回由$q.all
生成的承诺,并且您将在resolve
中进一步返回该承诺。
错误是你没有创建一个promises数组,而是你将一个延迟对象推入数组。
所以,改变它:
var promises = [];
var teamDefer = $q.defer();
promises.push(teamDefer.promise);
UserService.team('me', function(data)
{
teamDefer.resolve(data);
}, function()
{
teamDefer.reject();
});
然后你可以返回$q.all()
(和你一样):
return $q.all(promises);
略偏离主题:
在我看来, promiseData
被错误地命名,可能表示存在误解。您应该将变量命名为您将获得的结果的名称。这将被注入您的控制器,不管它是否来自承诺。因此,最好将它命名为team
(或类似的东西)
答案 1 :(得分:2)
您的代码的问题在于您将延迟放入数组中,而不是承诺。
就此而言,延期很快就会过时了。做出承诺(与ES6 API一致)的首选方法是使用promise constructor:
function resolveHomeTeam() {
var promises = [];
promises.push($q(function (resolve, reject) {
UserService.team('me', resolve, reject);
}));
return $q.all(promises);
}
请注意这也使您的代码更加清晰。
如果你想:
,你也可以把这个全部合并成一个陈述function resolveHomeTeam() {
return $q.all([
$q(function (resolve, reject) {
UserService.team('me', resolve, reject);
})
]);
}