1

我想为我的服务提供商创建一个链式承诺:

this.$get = function($q, $window, $rootScope) {
    var $facebook=$q.defer();

    $rootScope.$on("fb.load", function(e, FB) {
        $facebook.resolve(FB);
    });

    $facebook.api = function () {
        var args=arguments;
        args[args.length++] = function(response) {
            $facebook.resolve(response);
        };

        $facebook.promise.then(function(FB) {
            FB.api.apply(FB, args);
        });

        return $facebook.promise;
    };

    return $facebook;
};

比我呼吁的承诺:$scope.user=$facebook.api("/me");

问题是因为deferred已经解决了,所以不要等到api方法解决它。

我如何才能以最后一个承诺等到最后一个承诺解决的方式链接它们?

4

1 回答 1

3

似乎您需要两个单独的 Promise 对象:一个用于 fb.load 事件,另一个用于 API 调用的结果。

尝试更改您的代码以阅读 -

this.$get = function($q, $window, $rootScope) {
    var apiLoaded=$q.defer();

    $rootScope.$on("fb.load", function(e, FB) {
        apiLoaded.resolve(FB);
    });
    // You should reject the promise if facebook load fails.

    $facebook.api = function () {
        var resultDefer = $q.defer(),
            args=arguments;

        args[args.length++] = function(response) {
            $rootScope.$apply(function() {
                resultDefer.resolve(response);
                // you should reject if the response is an error
            });
        };

        return apiLoaded.promise.then(function(FB) {
            FB.api.apply(FB, args);
            return resultDefer.promise;
        });
    };

    return $facebook;
};

另请注意,无论何时从非 angularish 代码调用 resolve(),都需要用 $rootScope.$apply() 包装它,否则将不会执行 promise 'then' 处理程序。祝你好运!

于 2013-09-11T16:05:00.960 回答