【问题标题】:Calling [promise's] resolve multiple times [duplicate]多次调用 [promise's] 解决 [重复]
【发布时间】:2018-01-25 08:04:45
【问题描述】:

我有这个函数,它在异步获取数据时返回一个承诺。如您所见,该承诺 ($watchCollection) 的代码中有观察者,它会持续观察数据并为每次更改触发承诺的解析功能。

我无法测试 then 是否会为每个解析函数调用多次触发一次。这可能吗?

this.getGridDataAndMetaData = function(viewId) {          

    return new Promise(function(resolve, reject) {

        dataStore.fetchView(viewId)
            .then(function(viewEntity) {

                var grid_groupement = viewEntity.descriptor.state ? viewEntity.descriptor.state.grid_groupement : undefined;
                var dataStoreEntities = viewEntity.getEntityType().getEntities();
                var dataStoreProperties = viewEntity.getEntityType().getProperties();

                var gridDataAndMetaData;

                $rootScope.$watchCollection(function() {
                        return dataStoreEntities;
                    },
                    function(newCollection, oldCollection) {    

                        if (!angular.equals(newCollection, {}))
                            formatDataStoreEntities(angular.copy(newCollection), grid_groupement)
                            .then(function(data) {  


                                gridDataAndMetaData = data;                                            

                                if (lastNewProperties != undefined && !angular.equals(lastNewProperties, [])) {
                                    data.viewEntity = viewEntity;
                                    data.grid_groupement = grid_groupement;
                                    data.properties = lastNewProperties;   

                                    resolve(data);
                                }
                            });

                    });

                $rootScope.$watchCollection(function() {
                        return dataStoreProperties;
                    },
                    function(newProperties, oldProperties) {                                    
                        lastNewProperties = angular.copy(newProperties);                                    
                        if (gridDataAndMetaData != undefined && !angular.equals(gridDataAndMetaData.valuesIdsEntitiesTabFormat, {})) {                                                        
                            generateServiceTabs(newProperties, function() {
                                data.viewEntity = viewEntity;
                                data.grid_groupement = grid_groupement;
                                data.properties = lastNewProperties;

                                resolve(data);
                            });
                        }
                    });
            }).catch(function(error) {
                console.error('%c getGridDataAndMetaData :: dataStore.fetchView(viewId):: error : ' + JSON.stringify(error), 'background: red; color: white; display: block;');
                reject(error);
            });


    });

}

【问题讨论】:

  • 我已经用回调替换了承诺,我无法测试它是否会在每次数据更新(=观察者执行)时运行。我更喜欢回调而不是为可观察模式使用更多库
  • ES6 承诺不是 AngularJS 承诺。 AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 拆分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。使用 $q 服务承诺.then 块带入 AngularJS 执行上下文。
  • 不要在 .then 块内使用观察者。它会导致内存泄漏。你想在这里完成什么?
  • 一个 Promise(Angular 或 JavaScript)只会被解决一次。一旦您调用了resolvereject,随后对它们中的任何一个的调用都将被完全忽略。您可能需要Observable,详情请参阅this question's answers

标签: javascript angularjs promise


【解决方案1】:

resolve 函数作为 Promise 执行器函数的参数最多执行一次。 Promise 只能完成一次。注意,给定dataStore.fetchView(viewId) 返回PromisePromise 构造函数不是必需的。

【讨论】:

  • 感谢您的快速回答,您认为哪种模式适合这种情况?
  • 您可以使用现有的.then() 而不使用Promise 构造函数。注意,没有尝试过angularjs。如果查询特定于 angularjs,请参阅@T.J.Crowder 回答
  • 你认为主函数的回调而不是承诺会多次工作吗?
  • 回调什么?
猜你喜欢
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 2017-07-07
相关资源
最近更新 更多