使用promises在angularJS中建模异步数据

时间:2014-04-16 01:40:53

标签: javascript angularjs promise deferred

我正在使用angularJS开发单页应用程序,并且存在存储异步数据的问题。

为了简单起见,我基本上有一个服务,它保存了我的一些数据模型,这些模型作为promises返回(因为它们可以在任何给定时间异步更新)。

我有一个角度表,可以在某个条件发生变化时更新这些模型。 我还有一个角度表,在某些条件发生变化时会使用这些数据。

我的问题是: 使用数据的手表在更新此数据的手表之前触发,导致它立即触发"陈旧"数据而不是新承诺。

代码示例:

angular.module('myApp', [])
.controller('myController', function($scope, $q, asyncDataService) {

    // This watch is called whenever we need to update the asyncData
    $scope.$watch('variableThatCausesUpdate', function(newValue) {

        // Set the async data to a new unresolved promise to reflect
        // its pending nature
        var newAsyncDataDeferred = $q.defer();
        asyncDataService.setAsyncData(newAsyncDataDeferred.promise);

        // fetch the async data (in my case it is an $http request. 
        // newAsyncDataPromise is the $http promise)
        var newAsyncDataPromise = fetchAsyncData();

        // resolve the newData promise with the result from this fetch
        newAsyncDataPromise.then(function(newAsyncDataResult) {
            // At this point the data is up to date
            newAsyncDataDeferred.resolve(newAsyncDataResult.data);
        });

    });

    // This watch is called to perform some action, 
    // but is watching the same variable as update
    $scope.$watchCollection('[variableThatCausesUpdate, someOtherVariable]', function(newValue) {

        // We want to ensure that our asyncData is up to date, 
        // since we will be using it in our action
        asyncDataService.getAsyncData().then(function(asyncData) {
            // Firing with the "stale" promise since it occurs before update
            someActionRequiringOurAsyncData(asyncData);
        })

        /*
            However I can fix the issue by doing this 
            (since it will be put at the end of the event queue)
            But this seems ugly and maybe is the result of a bad design?
            setTimeout(function() {
                asyncDataService.getAsyncData().then(function(asyncData) {
                    someActionRequiringOurAsyncData(asyncData);
                })
            }, 0)

        */
    });

});

我可以在调用promise之前使用setTimeout 0来解决这个问题,以确保更新首先发生,但这感觉很糟糕,我开始感觉我正在接近错误的问题方向。

当然,我可以随时请求数据,但这会导致大量无关的请求。

我不能仅仅看到已解决的承诺的结果,因为其他变量也可以触发此监视,因此它不仅会在特定数据更新时触发。

1 个答案:

答案 0 :(得分:0)

为什么不完全删除第一个观察者,因为你在下面的集合中得到了相同的var。

angular.module('myApp', [])
.controller('myController', function($scope, $q, asyncDataService) {

    // This watch is called to perform some action, 
    // but is watching the same variable as update
    $scope.$watchCollection('[variableThatCausesUpdate, someOtherVariable]', function(newValue) {


        // We want to ensure that our asyncData is up to date, 
        // since we will be using it in our action
        asyncDataService.fetchAsyncData().then(function(asyncData) {
            // Firing with the "stale" promise since it occurs before update
            someActionRequiringOurAsyncData(asyncData);
        })  

    });

});