当承诺链中有错误时,如何回滚更改 [英] How to roll back changes when there is an error in a promise chain
问题描述
如果任何承诺发生错误,我想回滚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屋!