【发布时间】:2016-07-29 22:09:44
【问题描述】:
我有一些代码可以使用 Breeze 保存数据,并报告多次保存的进度,这些代码运行良好。 但是,有时保存会超时,我想自动重试一次。 (目前用户显示错误,必须手动重试) 我正在努力寻找合适的方法来做到这一点,但我对承诺感到困惑,所以我很感激一些帮助。 这是我的代码:
//I'm using Breeze, but because the save takes so long, I
//want to break the changes down into chunks and report progress
//as each chunk is saved....
var surveys = EntityQuery
.from('PropertySurveys')
.using(manager)
.executeLocally();
var promises = [];
var fails = [];
var so = new SaveOptions({ allowConcurrentSaves: false});
var count = 0;
//...so I iterate through the surveys, creating a promise for each survey...
for (var i = 0, len = surveys.length; i < len; i++) {
var query = EntityQuery.from('AnsweredQuestions')
.where('PropertySurveyID', '==', surveys[i].ID)
.expand('ActualAnswers');
var graph = manager.getEntityGraph(query)
var changes = graph.filter(function (entity) {
return !entity.entityAspect.entityState.isUnchanged();
});
if (changes.length > 0) {
promises.push(manager
.saveChanges(changes, so)
.then(function () {
//reporting progress
count++;
logger.info('Uploaded ' + count + ' of ' + promises.length);
},
function () {
//could I retry the fail here?
fails.push(changes);
}
));
}
}
//....then I use $q.all to execute the promises
return $q.all(promises).then(function () {
if (fails.length > 0) {
//could I retry the fails here?
saveFail();
}
else {
saveSuccess();
}
});
编辑 为了澄清我为什么一直在尝试这个: 我有一个 http 拦截器,它为所有 http 请求设置超时。当请求超时时,超时时间会向上调整,向用户显示一条错误消息,告诉他们如果愿意,可以等待更长的时间重试。
在一个 http 请求中发送所有更改看起来可能需要几分钟,所以我决定将更改分解为几个 http 请求,并在每个请求成功时报告进度。
现在,批处理中的一些请求可能会超时,而另一些可能不会。
然后我有了一个好主意,我会为 http 请求设置一个低超时时间并自动增加它。但是批次是异步发送的,具有相同的超时设置,并且每次失败都会调整时间。这样不好。
为了解决这个问题,我想在批处理完成后移动超时调整,然后重试所有请求。
说实话,我不太确定自动超时调整和重试是否是一个好主意。即使是这样,在一个接一个地发出 http 请求的情况下可能会更好 - 我也一直在关注:https://stackoverflow.com/a/25730751/150342
【问题讨论】:
-
$q.all无论如何都会失败。您可以在每个承诺解决之前进行错误捕获并在$q.all之前处理错误。 -
我的意思是,不是将一个简单的承诺推入数组,而是推一个尝试 n 次的函数来解决该承诺,如果失败,那么一切都会失败,您应该只处理
$q.all函数的最终结果。 -
实际上,我发现
$q.all总是成功 - 这就是为什么我在传递给then的第一个函数中检查fails.count()。我在其他地方有什么问题吗? -
但是推送一个尝试 n 次来解决该承诺的函数仍然对我有用。我该怎么做?
-
我发布了答案。
标签: promise breeze angular-promise