提问者:小点点

AngularJS:在服务中链接httppromise$Q


当涉及到AngularJS中的$HTTP承诺时,我有问题。我在我的服务中这样做:(getSomething函数应该链接两个承诺)

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

app.service('blubb', function($http, $q) {

  var self = this;

  this.getSomething = function(uri, data) {
    return self.getData(uri).then(function(data2) {
      return self.compactData(uri, data2);
    });
  };

  this.getData = function(uri) {
    var deferred = $q.defer();
    $http.get(uri).success(function(data) {
      deferred.resolve(data);
    }).error(function() {
      deferred.reject();
    });

    return deferred.promise;
  };

  this.compactData = function(uri, data) {
    var deferred = $q.defer();
    /* callback function */
      if(!err) {
        console.log(compacted);
        deferred.resolve(compacted);
      } else {
        console.log(err);
        deferred.reject(err);
      }
    /* end of function */

    return deferred.promise;
  };
});

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

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

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

    jsonld.compact(input, context, function(err, compacted) {
      if(!err) {
        console.log(compacted);
        deferred.resolve(compacted);
      } else {
        deferred.reject('JSON-LD compacting');
      }
    });

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

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


共3个答案

匿名用户

我用这样的链接承诺:

            $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);
                });

匿名用户

链接承诺在这里起作用:jsfiddle

在您的实现中,如果$HTTP.GETCompactData出错,则不会调用console.log(data)

您可能应该捕获错误:

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

匿名用户

每当您使用在新的turn/tick中运行的外部(AngularJS外部)回调时,您必须在调用$apply()之后在适当的作用域上调用它。这让AngularJS知道它必须更新。您可能希望确保您只调用它一次--在所有的承诺都得到解决之后。顺便说一句,jsonld.js提供了一个promessions/future API,因此如果您已经在使用promessions,就不必执行上面的包装器代码。相反,您可以执行以下操作:

var promisesApi = jsonld.promises();
var promise = promisesApi.compact(input, context);

// do something with the promise