在 AngularUI 路由器中访问多个承诺数据
Access multiple promises data in AngularUI router
我正在尝试使用 $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'
}
}
});
这是位于 Resolve
服务中的 resolveHomeTeam
函数:
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);
}
正如您在本例中看到的那样,我只将一个 promise 推送到数组中,我确信它正在被解析。
既然唯一的承诺被解决了,那么 $q.all()
返回的承诺不应该也被解决了吗? promiseData
数据不应该注入 SegmentHomeTeamCtrl
控制器吗?
如果我尝试在 SegmentHomeTeamCtrl
控制器中输出 promiseData
,我会得到整个承诺,其中还包含服务器购买返回的实际数据,由于某些原因我无法访问它。
您几乎所有事情都做对了:您正在 return 由 $q.all
生成的承诺,并且您正在 return 在 resolve
中进一步 return。
错误在于您没有创建承诺数组,而是将延迟对象推入数组。
所以,像这样改变它:
var promises = [];
var teamDefer = $q.defer();
promises.push(teamDefer.promise);
UserService.team('me', function(data)
{
teamDefer.resolve(data);
}, function()
{
teamDefer.reject();
});
然后你可以return $q.all()
(像你一样):
return $q.all(promises);
有点跑题:
promiseData
命名不正确,在我看来,这可能表明存在误解。您应该将变量命名为您将获得的结果的名称。这就是将被注入到您的控制器中的内容,它不会关心它是否来自承诺。因此,最好将其命名为 team
(或类似名称)
您的代码的问题是您将 deferred 放入数组,而不是承诺。
在这一点上,延期很快就会过时。做出承诺的首选方式(并且与 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);
})
]);
}
我正在尝试使用 $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'
}
}
});
这是位于 Resolve
服务中的 resolveHomeTeam
函数:
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);
}
正如您在本例中看到的那样,我只将一个 promise 推送到数组中,我确信它正在被解析。
既然唯一的承诺被解决了,那么 $q.all()
返回的承诺不应该也被解决了吗? promiseData
数据不应该注入 SegmentHomeTeamCtrl
控制器吗?
如果我尝试在 SegmentHomeTeamCtrl
控制器中输出 promiseData
,我会得到整个承诺,其中还包含服务器购买返回的实际数据,由于某些原因我无法访问它。
您几乎所有事情都做对了:您正在 return 由 $q.all
生成的承诺,并且您正在 return 在 resolve
中进一步 return。
错误在于您没有创建承诺数组,而是将延迟对象推入数组。
所以,像这样改变它:
var promises = [];
var teamDefer = $q.defer();
promises.push(teamDefer.promise);
UserService.team('me', function(data)
{
teamDefer.resolve(data);
}, function()
{
teamDefer.reject();
});
然后你可以return $q.all()
(像你一样):
return $q.all(promises);
有点跑题:
promiseData
命名不正确,在我看来,这可能表明存在误解。您应该将变量命名为您将获得的结果的名称。这就是将被注入到您的控制器中的内容,它不会关心它是否来自承诺。因此,最好将其命名为 team
(或类似名称)
您的代码的问题是您将 deferred 放入数组,而不是承诺。
在这一点上,延期很快就会过时。做出承诺的首选方式(并且与 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);
})
]);
}