延期承诺值未更新/解析/延期

deferred promise value not updating/resolving/deferring

本文关键字:解析 延期 更新 承诺      更新时间:2023-09-26

我有一个控制器函数,它可以创建一些东西。当调用该函数时,会运行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);
})();

当我在服务getStatus中检查response的值时,每次调用它时,状态都会发生变化(队列->处理…处理->创建)。然而,控制器status的值始终为queue

如何解决承诺值?

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

此外,它们应该在每次调用时创建并返回一个唯一的promise,而不是每次调用时都返回相同的promise。记住,承诺是单向状态机。一旦被解决或拒绝,它们的状态永远不会改变,即使对它们再次调用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;
    }