在 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);
        })
    ]);
}