AngularJS Chaining Promises不会绑定到模板

时间:2014-04-17 05:59:12

标签: angularjs promise

我似乎无法弄清楚为什么在使用promises后它仍然没有等待,所以$ scope.return_message返回null。

function getRandomCommit()
    {
        var d = $q.defer();
        $scope.repos = Repos.query({username: 'octocat'}).$promise.then(function ( value )
        {
            var ranNum = Math.floor((Math.random()*value.length) + 1);
            $scope.repo = Repo.get({username: 'octocat'}, {repo: value[ranNum].name}).$promise.then(function ( value2 )
            {
                $scope.commits = Commit.query({username: 'octocat'}, {repo: value2.name}).$promise.then(function ( value3 )
                {
                    var ranNum2 = Math.floor((Math.random()*value3.length));
                    d.resolve(value3[ranNum2].commit.message);
                    return d.promise;
                });
            });
        });
    };
    $scope.return_message = getRandomCommit();`

3 个答案:

答案 0 :(得分:6)

AngularJS 1.1.x和1.0.x包含一些称为展开承诺的实验性功能。您可以将承诺传递给模板,一旦解决,模板将自动使用已解析的值而不是承诺对象本身。

非常酷,对吧?这可能听起来像一个很好的功能,但事实上它 毕竟是有用的。它为AngularJS添加了太多逻辑,降低了评估速度并使模板/控制器中的代码不清楚。 AngularJS的工作人员评论了GitHub:

  

这个功能并没有被证明是非常有用或受欢迎的,   主要是因为模板中数据访问之间的二分法   (作为原始值访问)和控制器代码(作为承诺访问)。

     

在大多数代码中,我们最终在控制器中手动解析promises   或者通过这种方式自动路由和统一模型访问。

因此它是deprecated in AngularJS 1.2.x

您现在的选择是:

  • 等待承诺解决并在$scope
  • 上设置变量
  • 强制启用展开承诺(在1.2中弃用并在1.3中删除,因此它不再是一个选项!)

使代码工作重构getRandomCommit以返回一个承诺:

function getRandomCommit () {
    var d = $q.defer();
    // your code ...
    return d.promise;
}

并更改$scope.return_message的内容:

getRandomCommit().then(resolved_value => {
    $scope.return_message = resolved_value;
});

如果你正在使用AngularJS 1.2,你仍然可以使用promises unwrapping,但请注意它在1.3版中已被弃用和删除。您可以在AngularJS 1.0->1.2 migration guide

中找到更多信息

编辑(2014-10-30):

最近AngularJS 1.3发布了。在这个分支中,承诺展开是removed completely

答案 1 :(得分:1)

将您的代码更改为

function getRandomCommit() {
  var d = $q.defer();
  // do async tasks
  // call d.resolve(data) when finish
  return d.promise;
}

getRandomCommit().then(function (data) {
  $scope.return_message = data;
});

答案 2 :(得分:0)

我的控制台中不再出现错误,bangarang可以看到正确的$ scope.return_message感谢@miszy

function getRandomCommit() { var d = $q.defer(); $scope.repos = Repos.query({username: 'octocat'}).$promise.then(function ( value ) { var ranNum = Math.floor((Math.random()*value.length) + 1); $scope.repo = Repo.get({username: 'octocat'}, {repo: value[ranNum].name}).$promise.then(function ( value2 ) { $scope.commits = Commit.query({username: 'octocat'}, {repo: value2.name}).$promise.then(function ( value3 ) { var ranNum2 = Math.floor((Math.random()*value3.length)); d.resolve(value3[ranNum2].commit.message); return d.promise; }); }); }); }; }); }); }); return d.promise; }; getRandomCommit().then(function( resolved_value ) { $scope.return_message = resolved_value; }); }]);