gpt4 book ai didi

javascript - $q.all(p1, p2).then() 似乎在两个 promise 都得到解决之前就被触发了

转载 作者:行者123 更新时间:2023-11-29 10:45:04 28 4
gpt4 key购买 nike

$resource promise 应该与 $q 兼容吗?也许我用错了。我有两个 $resource 对象,我可以像这样加载:

$rootScope.foos = Res1.query();    // [ foo1, foo2...]
$rootScope.bars = Res2.query(); // [ bar1, bar2...]

我需要在两个(且只有两个)查询都到达时广播一个事件。所以我使用 $q.all 是这样的:

$q.all([$rootScope.foos.$promise, $rootScope.bars.$promise])
.then(function(){
// sometimes $rootScope.bars == []
$rootScope.$broadcast('foos_and_bars!');
});

事件监听器发现 $rootScope.bars 为空/[](一秒后它有数据)


更新以回应@Daiwei 和@ExpertSystem

好的,这里是 JSFiddle: Reproducing JSFiddle

控制台显示 $q.all() 在 promise 被解决之前被返回。我想要么它被错误使用,要么它是一个与 [$resource, $scope, $http, etc.] 中的任何一个有关的 Angular 错误...

最佳答案

更新:

原来是版本冲突的问题。下面提供的解决方案适用于更高版本(使用 1.2.8 测试),但完全多余。
参见 Purrell's answer 了解更多信息。


引用上的文档$resource :

It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. Having an empty object results in no rendering, once the data arrives from the server then the object is populated with the data and the view automatically re-renders itself showing the new data. This means that in most cases one never has to write a callback function for the action methods.
[...]
The Resource instances and collection have these additional properties:

  • $promise: ...
  • $resolved: ...

您的Res1Res2 是$resource 对象(不是实例)并且(根据文档)调用 query() 方法“立即返回一个空引用”(在您的例子中是一个数组)。 (UPD:返回的数组仍然具有额外的属性。)

正如文档所建议的那样,大多数时候您只是将这些空引用分配给作用域而忘记它们(一旦获取数据,模型(以及随后的 View )将自动更新)。


但是,如果您确实有理由希望在数据出现后立即得到明确通知,您可以使用两个“真实” promise :

// Create two deferred objects
var deferred1 = $q.defer();
var deferred2 = $q.defer();

// As soon as the data arrives, resolve the deferred objects
$rootScope.foos = Res1.query(function () { deferred1.resolve(); });
$rootScope.bars = Res2.query(function () { deferred2.resolve(); });

// Combine their promises using `$q.all()`
$q.all([deferred1.promise, deferred2.promise]).then(...);

另请参阅此 working example .


更新

由于返回的数组也有$promise属性,更简洁的版本是:

$rootScope.foos = Res1.query();
$rootScope.bars = Res2.query();

$q.all([$rootScope.foos.$promise, $rootScope.bars.$promise]).then(...);

Working demo

关于javascript - $q.all(p1, p2).then() 似乎在两个 promise 都得到解决之前就被触发了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21104768/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com