如何在promise链中出现错误时回滚更改

时间:2013-12-31 13:36:46

标签: angularjs error-handling firebase promise angularfire

在我的角度应用程序中,我希望通过混合事务和设置对我的firebase中的多个位置进行更改。我用a little help写了一个承诺链。现在我需要处理可能发生的任何错误。

如果任何承诺出现错误,我会想要回滚在firebase中做出的任何更改(成功的承诺),并提醒用户注意失败。

下面的当前代码

$scope.addNewPost = function() {
  var refPosts = new Firebase(FBURL).child('/posts').push();
  // Get tags into array for incrementing counters
  var tags = $scope.post.tags.split(', ');
  var allPromises = [];
  // Iterate through tags and set promises for transactions to increment tag count
  angular.forEach(tags, function(value, index){
    var dfd = $q.defer();
    var refTag = new Firebase(FBURL).child('/tags/' + value);
    refTag.transaction( function (current_value) {
      return current_value + 1;
    }, function(error, committed, snapshot) {
      if (committed) {
        dfd.resolve( snapshot );
      } else {
        dfd.reject( error );
      }
    });
    allPromises.push( dfd.promise );
  });

  // Add promise for setting the post data
  var dfd = $q.defer();
  refPosts.set( $scope.post, function (error) {
    if (error) {
      dfd.reject(error);
    } else {
      dfd.resolve('post recorded');
    }
  });
  allPromises.push( dfd.promise );

  $q.all( allPromises ).then(
    function () {
      $scope.reset(); // or redirect to post
    },
    function (error) {
      // error handling goes here how would I
      // roll back any data written to firebase
      alert('Error: something went wrong your post has not been created.');
    }
  );
};

所以我需要知道的是,如果其中一个承诺失败,我如何回滚发生在我的firebase数据上的任何更改。 firebase中可能会发生任意数量的更新。 (例如:通过事务递增3个标签并设置发布数据)

如何编写失败函数来计算成功的内容并将其撤消?如果这是可能的话。

---------------来自原帖的子问题已经解决---------------

另外你怎么强迫错误?我尝试设置如下变量,但它似乎没有用,我的.then有什么问题吗?

refPosts.set( $scope.post, function (error) {
  var forceError = true;
  if (forceError) {
    dfd.reject(forceError);
  } else {
    dfd.resolve('post recorded');
  }
  allPromises.push( dfd.promise );
});

1 个答案:

答案 0 :(得分:0)

这一行有两个实例,它们都在错误的位置:

allPromises.push( dfd.promise );
  • 在第一个块中,它应该位于forEach回调的最后一个语句中,而不是在事务回调中。
  • 在第二个区块中,它应该在调用set()之后,而不是在回调中。

现在编写代码的方式,$q.all()正在获得一个空数组的承诺。这也可能是干扰您正在尝试的forceError测试。