当承诺链中有错误时,如何回滚更改 [英] How to roll back changes when there is an error in a promise chain

查看:131
本文介绍了当承诺链中有错误时,如何回滚更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的有角度的应用程序中,我想通过交易和设置的混合来更改我的firebase中的几个位置。我已经写了一个承诺链,一点帮助。现在我需要处理可能发生的任何错误。



如果任何承诺发生错误,我想回滚firebase中的任何更改(



以下代码

  $ scope.addNewPost = function(){
var refPosts = new Firebase(FBURL).child('/ posts')。push();
//获取标记到数组中以递增计数器
var tags = $ scope.post.tags.split(',');
var allPromises = [];
//通过标签迭代并设置事务承诺以增加标签计数
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;
} ,功能(错误,提交,快照){
if(committed){
dfd.resolve(snapshot);
} else {
dfd.reject(error);
}
});
allPromises.push(dfd.promise);
});

//添加承诺设置帖子数据
var dfd = $ q.defer();
refPosts.set($ scope.post,function(error){
if(error){
dfd.reject(error);
} else {
dfd .resolve('post records');
}
});
allPromises.push(dfd.promise);

$ q.all(allPromises).then(
function(){
$ scope.reset(); //或重定向到post
},
函数(错误){
//错误处理在这里我将如何
//回滚写入firebase的任何数据
alert('错误:发生错误您的帖子没有被创建。');
}
);
};

所以我需要知道的是如何回滚我的firebase数据发生的任何更改这些承诺之一失败的事件。 Firebase中可能会有任何数量的更新。 (例如:3个标签通过事务递增,后置数据被设置)



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



---------------原始帖子的小问题已经解决了--------- ------



还有如何强制错误?我已经尝试设置一个如下所示的变量,但似乎不起作用,是否有什么问题?。

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


解决方案

这行有两个实例,都在错误的地方:

  allPromises.push(dfd.promise); 




  • 在第一个块中,应该在最后一个语句中对于每个回调,不在事务回调中。

  • 在第二个块中,应该是在调用 set()之后在回调中。



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


In my angular app I want to make changes to several locations in my firebase with a mix of transactions and set. I have written a promise chain with a little help. Now I need to handle any errors that may occur.

In the event of an error on any of the promises I would want to roll back any changes made in firebase (the successful promises) and alert the user to the failure.

Current code below

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

So what I need to know is how do I roll back any changes that happen to my firebase data in the event that one of these promises fail. There could be any number of updates happening in firebase. (for example: 3 tags being incremented via transaction and the post data being set)

How would I write the failure function to calculate what was successful and undo it? If this is this even possible.

--------------- sub question from original post has been solved ---------------

Also how do you force errors? I've tried setting a variable like below but it doesn't seem to work, is there something wrong with my .then?

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

解决方案

There are two instances of this line, and they are both in the wrong place:

allPromises.push( dfd.promise );

  • In the first block, it should be in the last statement in the forEach callback, not in the transaction callback.
  • In the second block, it should be after the call to set(), not in the callback.

The way your code is written now, $q.all() is getting an empty array of promises. That could also be what's interfering with the forceError test you're attempting.

这篇关于当承诺链中有错误时,如何回滚更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆