【问题标题】:AngularJS : chaining http promises $q in a serviceAngularJS:在服务中链接 http 承诺 $q
【发布时间】:2013-05-02 09:43:34
【问题描述】:

当谈到 angularjs 中的 $http 承诺时,我遇到了问题。我在我的服务中这样做:(getSomething 函数应该链接两个承诺)

第二个函数使用外部回调函数!

app.service('blubb', 函数($http, $q) { 变种自我=这个; this.getSomething = 函数(uri,数据){ 返回 self.getData(uri).then(function(data2) { 返回 self.compactData(uri, data2); }); }; this.getData = 函数(uri){ var deferred = $q.defer(); $http.get(uri).success(函数(数据) { deferred.resolve(数据); }).error(函数() { deferred.reject(); }); 返回 deferred.promise; }; this.compactData = 函数(uri,数据){ var deferred = $q.defer(); /* 回调函数 */ 如果(!错误){ console.log(压缩); deferred.resolve(压缩); } 别的 { 控制台日志(错误); deferred.reject(err); } /* 函数结束 */ 返回 deferred.promise; }; });

当我在控制器中使用该服务时,它不会输出 console.log:

blubb.getSomething(uri, input).then(function(data) { 控制台日志(数据) });

编辑: 如果我自己在“compactData”中定义回调函数,它可以工作,但我使用https://raw.github.com/digitalbazaar/jsonld.js/master/js/jsonld.js 的“jsonld.compact”,这不起作用!

jsonld.compact(输入,上下文,函数(错误,压缩){ 如果(!错误){ console.log(压缩); deferred.resolve(压缩); } 别的 { deferred.reject('JSON-LD 压缩'); } });

我在 jsonld.compact 中获得了 console.log 输出,但解析不起作用,我不知道为什么..

它只适用于 $rootScope.$apply(deferred.resolve(compacted));

【问题讨论】:

  • 除非compacted 被定义在某个地方并且在范围内,那么您可能想要将deferred.resolve(compacted); 更改为deferred.resolve("compacted");,并且err 可能相同。
  • sry,compactederr 是由回调函数定义的!在这个函数中,console.log(compacted) 也有正确的输出,但在“链式”getSomething 函数中没有。
  • 如果还是不行,那么在测试blubb.getSomething()之前分别测试blubb.getData()blubb.compactData()
  • 我使用了$rootScope.$apply,它有效! (请参阅stackoverflow.com/questions/14529354/…)但我收到此错误:Error: $digest already in progress
  • 请分享完整的小提琴,因为问题中没有给出很多东西

标签: angularjs promise deferred


【解决方案1】:

我正在使用这样的链接承诺:

            $http.get('urlToGo')
                .then(function(result1) {
                    console.log(result1.data);
                    return $http.get('urlToGo');
                }).then(function(result2) {
                    console.log(result2.data);
                    return $http.get('urlToGo');
                }).then(function(result3) {
                    console.log(result3.data);
                });

【讨论】:

    【解决方案2】:

    链式承诺在这里有效:jsfiddle

    在您的实现中,如果$http.getcompactData 出错,您的console.log(data) 将不会被调用。

    你可能会发现错误:

        blubb.getSomething(uri, input).then(function(data) {
           console.log(data);    
        }, function(err) {
           console.log("err: " + err);
        });
    

    【讨论】:

    • 我不知道为什么,但即使我注销错误也没有输出。但是当我使用$rootScope.$apply 时它工作得很好......但是我现在得到Error: $digest already in progress
    【解决方案3】:

    每当您使用在新的回合/滴答声中运行的外部(AngularJS 外部)回调时,您必须在调用 $apply() 后在适当的范围内调用它。这让 AngularJS 知道它必须更新。您可能希望确保只调用一次 - 在所有承诺都已解决之后。顺便说一句,jsonld.js 提供了一个 promises/future API,因此如果您已经在使用 promises,则不必执行上面的包装代码。相反,您可以这样做:

    var promisesApi = jsonld.promises();
    var promise = promisesApi.compact(input, context);
    
    // do something with the promise
    

    【讨论】:

      【解决方案4】:

      我建议您使用工厂而不是服务。

      只需从工厂返回功能并在控制器中使用它

      【讨论】:

        猜你喜欢
        • 2016-04-24
        • 1970-01-01
        • 2015-04-15
        • 2014-10-31
        • 1970-01-01
        • 2015-02-04
        • 2013-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多