如何判断 request/promise 完成时间是否超过 5 秒,angular js

how to tell if a request/promise takes longer than 5 seconds to fulfill, angular js

我是一名新开发人员,我正在尝试检查 promise 是否在 5 秒后未得到解决。在不创建新 directive/service/factory 的情况下,最易读的方法是什么?这是我尝试过的方法,我的主要问题是,当实例化 promise 变量时,我是否在正确的时间设置了时间间隔?

  $scope.promiseTimeLimit = false;
      //if the promise does not return within 5 seconds, show a "service down" warning.
      var promise = service.checkValidRailCar($scope.railcar.number, $scope.railcar.initials);

      $interval(function () {
        $scope.promiseTimeLimit = true
      }, 5000)

      if ($scope.promiseTimeLimit) {
        $scope.message = {
          content: [{
            title: '',
            msg: 'The Service Is Down'
          }],
          type: 'error'
        };
        return;
      }
      promise.then(function (data) {
        if (!data.valid) {
          $scope.invalidData = true;
          $scope.message = {
            content: [{
              title: '',
              msg: 'Invalid: This is not a valid data and can not be created.'
            }],
            type: 'error'
          };
        } else {
          $scope.invalidData = false;
        }
      })

是的,你已经正确设置了promise实例化后的时间间隔。但是,我认为您不想在这里使用 $interval。您可能想要使用 $timeout$interval 中的回调函数将被一次又一次地调用,除非您清除 $interval$timeout 中的回调函数只会被调用一次。如果你只想检查一次承诺是否在 5 秒内得到解决,你应该使用 $timeout.

第二件事是关于下面的代码:

if ($scope.promiseTimeLimit) {
    $scope.message = {
      content: [{
        title: '',
        msg: 'The Service Is Down'
      }],
      type: 'error'
    };
    return;
}

您需要将此代码保存在 $timeout 函数中。为了更好地理解,我将变量名 $scope.promiseTimeLimit 更改为 $scope.promiseComplete 并将其初始化为 $scope.promiseComplete = false.

$timeout(function () {
    if(!$scope.promiseComplete) {
        $scope.message = {
          content: [{
            title: '',
            msg: 'The Service Is Down'
          }],
          type: 'error'
        };
     }
}, 5000);

然后,在promise.then函数(resolve)中,需要将$scope.promiseComplete设置为true。

promise.then(function (data) {
    $scope.promiseComplete = true;
    if (!data.valid) {
      ...
})

那么,这里发生了什么? $timeout 回调函数将在 5 秒或之后调用。它将检查 $scope.promiseComplete 是否为假。如果为 false,则生成一条警告消息。如果为真,什么也不做。在 promise.then 中,我们将 $scope.promiseComplete 设置为 true。因此,如果 promise.then function(resolve) 在调用 $timeout 回调函数之前将 $scope.promiseComplete 设置为 true,这意味着 promise 在 5 秒之前完成。

我创建了一个示例 plunker 来理解这种行为。你可以看看HERE.

恕我直言,承诺超时应该作为拒绝来实现,并且像承诺一样,应该在尽可能低的级别上实现。

事实上,异步超时实际上是 window.setTimeout()race 中与您要调用的任何异步服务方法的承诺。

你可以这样写,例如:

service.checkValidRailCarWithTimeout = function(t, railcarNumber, railcarInitials) {
    // range checks
    if(t === undefined || railcarNumber === undefined || railcarInitials === undefined) {
        return $q.reject(new RangeError('Invalid parameter(s)'));
    }
    // race - timeout versus service call
    return $q(function(resolve, reject) {
        var tRef = window.setTimeout(function() {
            reject(new Error('The Service Is Down');
        }, t);
        function kill() {
            window.clearTimeout(tRef);
        };
        service.checkValidRailCar(railcarNumber, railcarInitials).then(resolve, reject).then(kill, kill);
    });
};

并调用如下:

var promise = service.checkValidRailCarWithTimeout(5000, $scope.railcar.number, $scope.railcar.initials).then(function(data) {
    $scope.invalidData = !data.valid;
    if (!data.valid) {
        throw new Error('Invalid: This is not a valid data and can not be created.');
    }
}).catch(function(error) {
    $scope.message = {
        content: [{
            title: '',
            msg: error.message
        }],
        type: 'error'
    };
});

备注:

  • $scope.promiseTimeLimit 的需求消失了
  • kill() 不是绝对必要的,但通过清除失去比赛的潜在超时来保持清洁。
  • $scope.message = ... 表达式将显示 error
  • 传递的任何消息