Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用promises在angularJS中建模异步数据_Javascript_Angularjs_Promise_Deferred - Fatal编程技术网

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

Javascript 使用promises在angularJS中建模异步数据,javascript,angularjs,promise,deferred,Javascript,Angularjs,Promise,Deferred,我正在用angularJS开发一个单页应用程序,在存储异步数据方面遇到了问题 为了简单起见,我基本上有一个服务,它保存一些作为承诺返回的数据模型(因为它们可以在任何给定时间异步更新) 我有一个有角度的手表,当某些条件改变时,它会更新这些模型。 我还有一个角度表,当某些条件改变时,它会使用这些数据 我的问题是: 使用数据的手表在更新此数据的手表之前启动,导致它立即使用“过时”数据而不是新的承诺启动 代码示例: angular.module('myApp', []) .controller('myC

我正在用angularJS开发一个单页应用程序,在存储异步数据方面遇到了问题

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

我有一个有角度的手表,当某些条件改变时,它会更新这些模型。 我还有一个角度表,当某些条件改变时,它会使用这些数据

我的问题是: 使用数据的手表在更新此数据的手表之前启动,导致它立即使用“过时”数据而不是新的承诺启动

代码示例:

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来修复此问题,以确保首先进行更新,但这感觉很糟糕,我开始觉得我从错误的方向解决了问题

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


我不能只观察已解决承诺的结果,因为其他变量也可以触发此手表,所以它不仅在特定数据更新时触发。

既然下面的集合中有相同的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);
        })  

    });

});

首先,不要在Angular中使用
setTimeout
,使用
$timeout
秒,在第一个承诺解决后,您可以在回调中启动第二个手表吗?此超时将无法确保您的数据是最新的。当你在你的本地机器上测试时,这会起作用…但是在100-200毫秒响应时间的真实环境中。你的架构很糟糕。我使用setTimeout是因为我不想触发不必要的摘要循环。除了触发摘要之外,还有什么理由使用$timeout吗?另外,为什么超时不能确保数据是最新的?更新和需要更新的操作总是在同一个摘要循环中触发,因此它只会将其中一个移动到事件循环的末尾。一旦更新被调用,承诺现在就无法解决,它将正确地等待它完成。它不依赖于超时的实际持续时间。也许我在这里遗漏了什么?这将解决必须使用超时的问题,但这意味着每次需要使用变量时我都会发出一个新的ajax请求(它使用得非常频繁,只是偶尔更新)。我想在本地缓存它,因为它只是偶尔更新。当前,它存储为已解决的承诺,直到需要更新为止,更新时为未解决的承诺,更新完成后再次为已解决的承诺。也许我应该设置缓存?但这可能会导致问题,因为同一请求可能并不总是有相同的响应。