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

时间:2021-12-14 15:53:51

I have a controller function that creates something. When the function is called, a setInterval run to get the status of the item.

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

Here is the service:

这是服务:

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

And here is the controller:

这是控制器:

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

When I check the value of the response in getStatus of the service, the status changes every time it is called (queue -> processing ... processing -> created). However, the value of status in the controller is always queue.

当我检查服务的getStatus中的响应值时,每次调用时状态都会更改(queue - > processing ... processing - > created)。但是,控制器中的状态值始终为队列。

How do I get the promise value to resolve?

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

1 个解决方案

#1


5  

createSomething() and getStatus() need to create and return their own promise. They can't share a promise and work properly in all cases.

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

In addition, they should create and return a unique promise each time they are called, not the same promise every time they are called. Remember, promises are one-way state machines. Once resolved or rejected, their state never changes, even if resolve() or reject() is called again on them.

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

Here's an example:

这是一个例子:

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

#1


5  

createSomething() and getStatus() need to create and return their own promise. They can't share a promise and work properly in all cases.

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

In addition, they should create and return a unique promise each time they are called, not the same promise every time they are called. Remember, promises are one-way state machines. Once resolved or rejected, their state never changes, even if resolve() or reject() is called again on them.

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

Here's an example:

这是一个例子:

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