У меня есть код, который сохраняет данные с помощью 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 .все' функция. –
На самом деле, я обнаружил, что '$ q.all' всегда преуспевает - вот почему я проверяю' fail.count() 'в первой функции, переданной' then'. У меня что-то случилось в другом месте? – Colin