延期承诺价值未更新/解决/延期

时间:2016-05-18 04:37:01

标签: javascript angularjs meteor promise

我有一个控制器功能可以创建一些东西。调用该函数时,运行setInterval以获取项目的状态。

这是服务:

(function () {
    'use strict';

    function myService($q) {
        let deferred = $q.defer();

        function createSomething(name) {
            Meteor.call('createSomething', name, (err, res) {
                if (err) {
                    deferred.reject(err);
                } else {
                    //value returned is the created item (id, name, status)
                    deferred.resolve(res);
                }
            });

            return deferred.promise;
        }

        function getStatus(id) {
            Meteor.call('getStatus', id, (err, res) {
                if (err) {
                    deferred.reject(err);
                } else {
                    //statuses are queued, processing, created
                    deferred.resolve(res);
                }
            });

            return deferred.promise;
        }

        return {
            createSomething: createSomething,
            getStatus: getStatus
        }
    }

    angular.module('myApp').factory('myService', myService);
})();

这是控制器:

(function () {
    'use strict';

    function myController($scope, myService) {
        let ctrl = this;

        ctrl.create = (name) => {
            myService.createSomething(name)
                .then((item) => {
                    ctrl.statusInterval = setInterval(() => {
                        myService.getStatus(item.data.id)
                            .then((status) => {
                                //status is always 'queued' :(
                                if (status.data.status === 'created') {
                                    clearInterval(ctrl.statusInterval);
                                    //do something
                                }
                            });
                    }, 5000);
                });
        };
    }

    angular.module('myApp').controller('myController', myController);
})();

当我检查服务responsegetStatus的值时,每次调用时状态都会更改(队列 - >处理...处理 - >创建)。但是,控制器status的值始终为queue

如何获得要解决的承诺值?

1 个答案:

答案 0 :(得分:5)

createSomething()getStatus()需要创建并返回自己的承诺。在所有情况下,他们都无法分享承诺并正常工作。

此外,他们应该在每次调用时创建并返回一个唯一的承诺,而不是每次调用时都有相同的承诺。请记住,承诺是单向状态机。解决或拒绝后,即使再次调用resolve()reject(),其状态也不会发生变化。

以下是一个例子:

    function createSomething(name) {
        // create a unique deferred inside this function each time you call it
        let deferred = $q.defer();
        Meteor.call('createSomething', name, (err, res) {
            if (err) {
                deferred.reject(err);
            } else {
                //value returned is the created item (id, name, status)
                deferred.resolve(res);
            }
        });

        return deferred.promise;
    }