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

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

问题描述

在我的 angular 应用程序中,我想通过事务和集合的组合对我的 Firebase 中的几个位置进行更改.我写了一个承诺链 一点帮助.现在我需要处理可能发生的任何错误.

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

下面的当前代码

$scope.addNewPost = function() {var refPosts = new Firebase(FBURL).child('/posts').push();//将标签放入数组以递增计数器var tags = $scope.post.tags.split(', ');var allPromises = [];//遍历标签并设置交易承诺以增加标签计数angular.forEach(标签,函数(值,索引){var dfd = $q.defer();var refTag = new Firebase(FBURL).child('/tags/' + value);refTag.transaction(函数(当前值){返回 current_value + 1;},函数(错误,提交,快照){如果(提交){dfd.resolve(快照);} 别的 {dfd.reject(错误);}});allPromises.push(dfd.promise);});//添加设置post数据的promisevar dfd = $q.defer();refPosts.set( $scope.post, function (error) {如果(错误){dfd.reject(错误);} 别的 {dfd.resolve('帖子记录');}});allPromises.push(dfd.promise);$q.all( allPromises ).then(功能 () {$scope.reset();//或重定向到帖子},功能(错误){//错误处理在这里,我将如何//回滚写入 firebase 的所有数据alert('错误:出现问题,您的帖子尚未创建.');});};

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

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

--------------- 原帖中的子问题已解决---------------

还有你如何强制错误?我试过设置一个像下面这样的变量,但它似乎不起作用,我的 .then 有什么问题吗?

refPosts.set( $scope.post, function (error) {var forceError = true;如果(强制错误){dfd.reject(forceError);} 别的 {dfd.resolve('帖子记录');}allPromises.push(dfd.promise);});

解决方案

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

allPromises.push(dfd.promise);

  • 在第一个块中,它应该在 forEach 回调的最后一个语句中,而不是在事务回调中.
  • 在第二个块中,它应该在调用 set() 之后,而不是在回调中.

按照您现在编写代码的方式,$q.all() 正在获取一个空的 Promise 数组.这也可能是干扰了您正在尝试的 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天全站免登陆