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

Apo*_*ani 5 promise angularjs angular-resource angular-promise

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

 $scope.module = moduleFactory.get({id: $stateParams.id})
    .$promise.then(function(response){
        $scope.module = response;
     }
Run Code Online (Sandbox Code Playgroud)

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

geo*_*awg 6

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

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

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

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

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

    失败时,使用http响应对象拒绝promise ,而不使用resource属性.

--AngularJS $资源服务API参考


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

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

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

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



对你来说一定是显而易见的,但是我在$ q.all()中使用了$ resource.$ promise的数组,并且它有效.

$ q.all适用于任何来源的承诺.在引擎盖下,它使用$ q.when将值或承诺(任何可用的对象)转换为$ q服务承诺.

$ q.allall其他promise库中的方法分开来的是,除了使用数组之外,它还适用于具有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
});
Run Code Online (Sandbox Code Playgroud)

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


Dun*_*can 6

您可以通过调用以 angular 构建承诺$q

 let promise = $q(function(resolve, reject) { ... };
Run Code Online (Sandbox Code Playgroud)

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

 let promise = $q.resolve(somevalue);
Run Code Online (Sandbox Code Playgroud)

还有一种较旧的方法$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 ...});
Run Code Online (Sandbox Code Playgroud)

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

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