Angularjs 如何解决$timeout内的承诺

Angularjs 如何解决$timeout内的承诺,angularjs,angular-promise,Angularjs,Angular Promise,对于回调,我将回调包装在一个有角度的$timeout块中,以便它更新UI function makeServerRequest(callback) { $timeout(callback); } makeServerRequest((response) => { $scope.updateUI(); }) 这在角度摘要周期内运行,并且UI得到更新 但是,这不起作用: function makeServerRequest() { return new Promise((res

对于回调,我将回调包装在一个有角度的$timeout块中,以便它更新UI

function makeServerRequest(callback) {
  $timeout(callback);
}

makeServerRequest((response) => {
  $scope.updateUI();
})
这在角度摘要周期内运行,并且UI得到更新

但是,这不起作用:

function makeServerRequest() {
  return new Promise((resolve, reject) => {
    $timeout(() => {
      resolve();
    });
  })
}

makeServerRequest().then(() => {
  $scope.updateUI();
})
在本例中,似乎发生了解析,然后
$scope.updateUI()在超时后调用


如何在超时内包装
resolve
,以便在超时内调用outside.then?

本机承诺不会触发摘要,在这种情况下应手动触发:

makeServerRequest().then(() => {
  $scope.updateUI();
  $scope.$apply()
})
$timeout已经返回了一个promise($q promise,这是对摘要友好的)。所以没有必要创建一个新的,特别是本地的

它可以是:

function makeServerRequest() {
  return $timeout(angular.noop, 100);
}

makeServerRequest().then(...);

您需要做的是从服务器请求API创建$q承诺:

function makeServerRequest() {
  return $q((resolve, reject) => {
     var callback = resolve;
     ServerRequest(callback);
  });  
}

makeServerRequest().then(() => {
  $scope.updateUI();
})
无需使用
$timeout
,因为$q服务与AngularJS框架及其摘要周期集成在一起


有关更多信息,请参阅。

因此,关键是返回$timeout对象?是的。setTimeout需要得到承诺才能成为承诺$超时不需要那个。不清楚为什么在makeServerRequest中使用超时,但我假设您模拟了它。最好使用
$q
而不是本机承诺,本机承诺具有将在摘要周期中评估的处理程序。最佳做法是避免ES6承诺。或者,如果来自第三方库,请将它们转换为AngularJS Promissions,可能重复。@georgeawg此最佳实践的唯一原因是否与摘要循环有关?AngularJS通过提供自己的事件处理循环来修改正常的JavaScript流。这将JavaScript分为经典和AngularJS执行上下文。只有在AngularJS执行上下文中应用的操作才会受益于AngularJS数据绑定、异常处理、属性监视等。AngularJS$q承诺与框架执行上下文集成。