如何检查Angular$q promise是否已解决



我知道,在使用promise时,通常只会附加带有then()调用和链行为的延续代码。

然而,我想启动一个promise包装的异步调用,然后单独启动一个3秒的$timeout(),这样我就可以执行UI操作,前提是原始promise尚未完成。(我预计这只会发生在慢速连接、3G移动设备等情况下。)

如果有承诺,我可以在不阻塞或等待的情况下检查它是否完整吗?

我想这是在Angular的最新版本中添加的,但现在promise上似乎有一个$$state对象:

 var deferred = $q.defer();
 console.log(deferred.promise.$$state.status); // 0
 deferred.resolve();
 console.log(deferred.promise.$$state.status); //1 

正如评论中所指出的,不建议这样做,因为在升级Angular版本时可能会中断。

我认为最好的选择是(在不修改Angular源代码和提交pull请求的情况下)保留一个本地标志,以确定promise是否已得到解决。每次设置您感兴趣的承诺时都将其重置,并在原始承诺的then()中将其标记为完成。在$timeout then()中,检查标志以了解原始承诺是否已解决。

类似这样的东西:

var promiseCompleted = false;
promise.then(function(){promiseCompleted=true;})
$timeout(...).then(function(){if(!promiseCompleted)doStuff()})

Kris-Kowal的实现包括其他检查promise状态的方法,但Angular对$q的实现似乎不包括这些方法。

正如@shunhusain已经提到的那样,这似乎是不可能的。但也许没有必要:

// shows stuff from 3s ahead to promise completetion, 
// or does and undoes it in one step if promise completes before
$q.all(promise, $timeout(doStuff, 3000)).then(undoStuff);

或者更好:

var tooSlow = $timeout(doStuff, 3000);
promise.always(tooSlow.cancel);

我也遇到过类似的问题,需要检查是否返回了promise。因为AngularJS的$watch函数在呈现页面时会注册更改,即使新值和旧值都未定义,我也必须检查是否有任何数据值得存储在我的外部模型中。

这绝对是一个黑客,但我这样做:

$scope.$watch('userSelection', function() {
  if(promiseObject.hasOwnProperty("$$v"){
    userExportableState.selection = $scope.userSelection;
  }
};

我知道$$v是AngularJS使用的一个内部变量,但它对我们来说是一个非常可靠的指标。谁知道当我们升级到AngularJS 1.2时会发生什么://我在1.2文档中没有看到任何关于$q的改进,但也许有人会写一个替代服务,它的功能集更接近Q。

我不知道你的确切场景,但更常见的是在进行异步调用(并生成promise)后立即设置超时。

如果setTimeout()语句与异步调用在同一事件线程中,则不必担心竞争效应的可能性。由于javascript严格来说是单线程的,promise的.then()回调保证会在以后的事件线程中触发。

相关内容

  • 没有找到相关文章

最新更新