嵌套承诺-更好的方式



我是一名新的开发人员,正在处理一个相当复杂的场景,在这个场景中,当用户保存时,可能会有一个锁,用户有机会超越这个锁。如果有锁,由于REST是无状态的,我在PUT上发送的对象就会丢失,所以我必须允许用户绕过锁,然后再次发出PUT请求。

在第二个if检查中,您可以看到我有一个嵌套的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);
      })
    }
  })

您将回调和承诺混合在一起,使其变得更加困难。所有异步函数都应该返回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);
      });
  }
});

如果你想要一个更干净的解决方案,你可以声明一个函数,用作用域id调用你的itemService.updateItem$scope.postPUTRequestActions,最终得到

$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);
      });
  }
});

这既易于理解又易于遵循。

这也很新鲜,但也许这会很有用。

另一个想法是,在返回promise的第一个函数中,您可能希望调用另一个函数并使用setTimeout(function2,"在此处插入毫秒"),但从长远来看,这可能会减慢速度,因为您希望在数据准备好后立即使用它。。。对我来说似乎很生气,但这可能是短期的绷带。

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

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!");
    }

希望这能有所帮助。

最新更新