в JavaScript, как обернуть обещание в тайм-аут?
Это общий шаблон для реализации тайм-аута некоторой асинхронной функции с использованием deffered / обещания:
// Create a Deferred and return its Promise
function timeout(funct, args, time) {
var dfd = new jQuery.Deferred();
// execute asynchronous code
funct.apply(null, args);
// When the asynchronous code is completed, resolve the Deferred:
dfd.resolve('success');
setTimeout(function() {
dfd.reject('sorry');
}, time);
return dfd.promise();
}
Теперь мы можем выполнить некоторую асинхронную функциюmyFunc
и обработать тайм-аут:
// Attach a done and fail handler for the asyncEvent
$.when( timeout(myFunc, [some_args], 1000) ).then(
function(status) {
alert( status + ', things are going well' );
},
function(status) {
alert( status + ', you fail this time' );
}
);
Хорошо, давайте сделаем поворот в этой истории! Представь, чтоmyFunc
Сам возвращает обещание (ПРИМЕЧАНИЕ: обещание НЕ отложено, и я не могу его изменить):
function myFunc(){
var dfd = new jQuery.Deffered();
superImportantLibrary.doSomething(function(data)){
if(data.length < 5){
dfd.reject('too few data');
}
else{
dfd.resolve('success!');
}
}, {'error_callback': function(){
dfd.reject("there was something wrong but it wasn't timeout");}
}});
return dfd.promise();
}
Теперь, если я завернуmyFunc
вtimeout
Я потеряю способность обрабатывать ошибки, отличные от времени ожидания. ЕслиmyFunc
излучать события прогресса, я это тоже потеряю.
Итак, вопрос: как изменитьtimeout
функция, чтобы он мог принимать функции, возвращающие обещания, не теряя свои ошибки / информацию о прогрессе?