angular1.x中$ promise和$ q promises有什么区别?

时间:2017-02-25 11:17:57

标签: angularjs promise angular-promise angular-resource

我开始使用angular中的promises来解析我的api调用,使用以下语法:

 $scope.module = moduleFactory.get({id: $stateParams.id})
    .$promise.then(function(response){
        $scope.module = response;
     }

现在,我遇到了一种情况,我必须在for循环中链接多个promise并在for循环中的所有promise都已解析后执行一些代码。我一直试图用$ promise语法搜索如何做到这一点,但互联网上的大多数消息来源都在谈论$ q。我是开发工作的新手,我发现在这两个概念($ q和$ promise)之间徘徊是非常困惑的。请你好心人:首先,向我解释$ promise和$ q之间的区别;第二,如果我决定使用$ q来解决我上面描述的当前问题,是否意味着我将不得不重写使用$ promise的代码,以使其可以像$ q.all()那样进行链接?

2 个答案:

答案 0 :(得分:5)

$promise$resource Service类类型操作方法返回的对象的属性。

  

重要的是要意识到调用$resource对象方法会立即返回一个空引用(对象或数组,具体取决于isArray)。从服务器返回数据后,将使用实际数据填充现有引用。

     

资源实例和集合具有以下附加属性:

     
      
  • $promise:创建此实例或集合的原始服务器交互的承诺。

         

    成功时,promise将使用相同的资源实例或集合对象解析,并使用来自服务器的数据进行更新。这使得在resolve section of $routeProvider.when()中使用它很容易推迟视图渲染,直到资源被加载。

         

    失败时,使用http response对象拒绝承诺,但没有资源属性。

  •   
     

--AngularJS $resource Service API Reference

注意:问题中的示例代码是多余的,不必要。

$scope.module = moduleFactory.get({id: $stateParams.id})
    .$promise.then(function(response){
        //REDUNDANT, not necessary
        //$scope.module = response;
    });

对$ scope的已解决响应的分配不是必需的,因为$resource将在结果来自服务器时自动填充引用。仅当代码需要在来自服务器之后使用结果时才使用$promise属性。

要区分返回承诺的其他服务返回$resource Service个对象的服务,请查找.then方法。如果对象具有.then方法,则它是一个承诺。如果它具有$promise属性,则它遵循ngResource模式。

对你来说一定是显而易见的,但我在$ {3}}中使用了一个$ resource。$ promise的数组,并且它有效。

$q.all()适用于来自任何来源的承诺。在幕后,它使用$q.all将值或承诺(任何可用的对象)转换为$q.when承诺。

除了使用其他promise库中的all方法之外,$q Service除了使用数组之外,它还适用于具有promises属性的JavaScript对象。可以制作promises的哈希(关联数组)并使用$q.all来解决它。

var resourceArray = resourceService.query(example);

var hashPromise = resourceArray.$promise.then(function(rArray) {
    promiseHash = {};
    angular.forEach(rArray,function (r) {
        var item = resourceService.get(r.itemName);
        promiseHash[r.itemName] = item.$promise;
    });
    //RETURN q.all promise to chain
    return $q.all(promiseHash);
});

hashPromise.then(function (itemHash) {
    console.log(itemHash);
    //Do more work here
});

上面的示例创建了一个由itemName索引的项的哈希,所有项都是从$q.all异步提取的。

答案 1 :(得分:4)

您可以通过调用$q来构建角度的承诺:

 let promise = $q(function(resolve, reject) { ... };

或者您只是想要一个立即解决的承诺:

 let promise = $q.resolve(somevalue);

使用$q.defer()构建延迟对象并返回它的.promise属性还有一种较旧的方法,但你应该避免这样做,并考虑它只是为了向后兼容

创建新承诺的最后一种方法是在现有承诺上调用.then()(或.catch())。

.$promise属性只是上述机制之一由$resource服务或遵循相同模式的内容创建的承诺。

一旦你有了一些承诺,你就可以将它们全部填入数组并使用$q.all()等待它们全部完成,或者让它们拒绝。或者,如果您希望按顺序发生事情,可以通过执行前一个承诺的.then()中的每个步骤将它们链接在一起:

 let promise = $q.resolve();
 for(... something ...) {
     promise = promise.then(() => { ... next step here ...});
 }
 promise.then(() => { ... runs when everything completed ...});

这将按顺序执行所有操作,而$q.all()将并行启动它们。有时候你想要一个,有时候想要另一个:

 let promises = [];
 for(... something ...) {
     promises.push(somethingThatReturnsAPromise());
 }
 $q.all(promises).then(() => { ... runs when everything completed ...});