无法执行链式承诺

Cannot execute chained promises

我需要使用 $http.jsonp 获取提要,然后我 return deferred.resolve(feed) 应该将 feed 值传递给链式函数 EntryStateUrlService.getEntryStateUrl.

出于某种原因,它说 FeedService.parseFeed(feedSrc) 被评估为 undefined 因此 then() 方法无法在 undefined 上调用。如何解决?

app.service('LoadData', ['FeedService', 'EntryStateUrlService', '$q', function(FeedService, EntryStateUrlService, $q) {
    var deferred = $q.defer();

    this.loadData = function(feedSrc) {

        FeedService.parseFeed(feedSrc).then(EntryStateUrlService.getEntryStateUrl).then(function(urls) {
            $rootScope.links = urls;
        });
    }
}]); //TypeError: undefined is not a function

app.service('FeedService', function($http, $q) {
    var deferred = $q.defer();

    this.parseFeed = function(url) {
        $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=JSON_CALLBACK&q=' + encodeURIComponent(url))
            .success(function(res) {

                deferred.resolve(res.data.responseData.feed.entries); //TypeError: Cannot read property 'responseData' of undefined
            }).error(function() {
                deferred.reject();
            });
 return deferred.promise(); //TypeError: object is not a function
    }
});
app.service('EntryStateUrlService', ['$state', '$q', function($state, $q) {
    var deferred = $q.defer();
    this.getEntryStateUrl = function(feeds) {
            var idx = 0;
            feeds.forEach(function(e) {
                $http.jsonp(e.link).success(function(data) {
                    /*stuff*/
                    deferred.resolve('root.' + generatedStateName);
                });
            }); //forEach
        } //getEntryStateUrl
return deferred.promise();
}]); //EntryStateUrlService

更新

return deferred.promise(); 添加到 EntryStateUrlServiceFeedService 之后,我在 FeedService 中得到 TypeError: object is not a function for return deferred.promise();

parseFeed 函数不应该返回延迟的吗?

this.parseFeed = function(url) {
    $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=JSON_CALLBACK&q=' + encodeURIComponent(url))
        .success(function(res) {

            deferred.resolve(res.data.responseData.feed.entries);
        }).error(function() {
            deferred.reject();
        });
    return deferred;
}

我在你的代码中遗漏了一个承诺。我认为您必须 return 在您的 FeedService 中做出承诺:return deferred.promise(); 而不是 return deferred;

在 FeedService return deferred.promise 中,同样在 EntryStateUrlService 中,在 forEach 中调用多个服务,因此如果在所有服务完成后需要解决承诺,请使用 $q.all 如下所示。

app.service('LoadData', ['FeedService', 'EntryStateUrlService', '$q', function(FeedService, EntryStateUrlService, $q) {
    this.loadData = function(feedSrc) {

        FeedService.parseFeed(feedSrc).then(EntryStateUrlService.getEntryStateUrl).then(function(urls) {
            $rootScope.links = urls;
        }, function(failureException) {
            // failure error handler comes here.        
        });
    }
}]); //TypeError: undefined is not a function

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

    this.parseFeed = function(url) {
        var deferred = $q.defer();
        $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=JSON_CALLBACK&q=' + encodeURIComponent(url))
            .success(function(res) {

                deferred.resolve(res.data.responseData.feed.entries); //TypeError: Cannot read property 'responseData' of undefined
            }).error(function() {
                deferred.reject();
            });
        return deferred.promise;
    }
});
app.service('EntryStateUrlService', ['$state', '$q', function($state, $q) {

    this.getEntryStateUrl = function(feeds) {

            var deferred = $q.defer();
            var idx = 0, promises = [];
            feeds.forEach(function(e) {
                $http.jsonp(e.link).success(function(data) {
                    /*stuff*/                    
                });
            }); //forEach

            // once all the jsonp service in the  for loop is finished, then resolve the promise
            $q.all(promises).then(function() {
                deferred.resolve('root.' + generatedStateName);
            }, deferred.reject);

            return deferred.promise;

        } //getEntryStateUrl
}]); //EntryStateUrlService