嵌套承诺 - 更好的方法?

时间:2016-05-16 17:31:31

标签: angularjs promise angular-promise

我是一名新开发人员,正在开发一个相当复杂的场景,当用户保存时,可能会出现锁定,并且用户有机会超越锁定。如果存在锁定,由于REST是无状态的,我在PUT上发送的对象将丢失,因此我必须允许用户过度锁定然后再次发出put请求。

在第二个if检查中,您可以看到我有一个嵌套的承诺。根据我对承诺与回调的了解,这违背了使用承诺的目的。我读了一些其他的答案,但是不理解在内部/嵌套的promise中返回promise的概念。我怎么能重构下面的代码,使其更符合最佳实践而不是嵌套承诺?

//the user chooses to over ride someone else's lock
  $scope.$on('forceLockAfterModalSubmit', function (e, data) {
    if (!$scope.newItemCreatedIsLocked) {
      $scope.setLockForCurrentUser();
      $scope.editMode = true;
    }
    if ($scope.newItemCreatedIsLocked) {
      service.forceLock($scope.id).then(function () {
        itemService.updateItem($scope.itemForRequestBeforeLockResponse).then(function () {
          $scope.postPUTRequestActions($scope.itemForRequestBeforeLockResponse);
        })
      }, function (err) {
        console.log(err);
      })
    }
  })

2 个答案:

答案 0 :(得分:2)

你正在混合回调和承诺,并使它变得比以往更难。 所有异步函数都应该返回一个promise,而不是使用第二个.then()作为错误处理程序,你应该让.catch()函数处理错误。

您目前的代码可以替换为

$scope.$on('forceLockAfterModalSubmit', function(e, data) {
  if (!$scope.newItemCreatedIsLocked) {
    $scope.setLockForCurrentUser();
    $scope.editMode = true;
  }
  if ($scope.newItemCreatedIsLocked) {
    service.forceLock($scope.id)
      .then(function() {
        return itemService.updateItem($scope.itemForRequestBeforeLockResponse);
      })
      .then(function() {
        return $scope.postPUTRequestActions($scope.itemForRequestBeforeLockResponse);
      })
      .catch(function(err) {
        console.log(err);
      });
  }
});

如果您想要一个更干净的解决方案,您可以声明一个功能,使用范围itemService.updateItem调用您的$scope.postPUTRequestActionsid并最终得到

$scope.$on('forceLockAfterModalSubmit', function(e, data) {
  if (!$scope.newItemCreatedIsLocked) {
    $scope.setLockForCurrentUser();
    $scope.editMode = true;
  }
  if ($scope.newItemCreatedIsLocked) {
    service.forceLock($scope.id)
      .then(itemService.updateItem)
      .then($scope.postPUTRequestActions)
      .catch(function(err) {
        console.log(err);
      });
  }
});

这很容易理解和遵循。

答案 1 :(得分:-1)

这也很新,但也许这可能有用。

另一个想法是,在第一个返回promise的函数中,你可能想要调用另一个函数并使用setTimeout(函数2,"在这里插入毫秒")虽然从长远来看会减慢速度因为你想在数据准备就绪后立即......对我来说似乎很苛刻,但它可能是短期的绷带。

在一个有点相关的说明中,你可能想要写出这样的东西来帮助提高可读性。



service.then(successFunction).catch(errorFunction);

function successFunction(response) {
    if (response == "Valid Data") {
      return response;
    } else {
      console.log("Something is wrong with the success function!");
      return response;
    }

    functon errorFunction(response) {
      console.log("Error occurred in the service!");
    }




希望这会有所帮助。