在JavaScript中,如何在超时中包装一个promise? [英] in JavaScript, how to wrap a promise in timeout?
问题描述
这是使用deffered / promise实现某些异步函数超时的常见模式:
It's a common pattern to implement timeout of some asynchronous function, using deffered/promise:
// 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 <的异步函数/ code>并处理超时:
Now we can execute some asynchronous function called myFunc
and handle timeout:
// 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
本身会返回一个承诺(注意:承诺不推迟,我无法更改):
OK, let's make a twist in this story! Imagine that the myFunc
itself returns a promise (NOTE: promise NOT deferred and I can't change it):
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
在超时
中,我将失去处理不同于超时的错误的能力。如果 myFunc
发出进度事件,我也会松开它。
Now if I wrap myFunc
in timeout
, I will loose the ability to handle errors different then timeout. If myFunc
emit progress events, I will loose this as well.
所以问题是:如何修改 timeout
函数所以它可以接受函数返回promises而不会丢失它们的错误/进度信息吗?
So the question is: how to modify timeout
function so it can accept functions returning promises without loosing their errors/progress information?
推荐答案
function timeout(funct, args, time) {
var deferred = new jQuery.Deferred(),
promise = funct.apply(null, args);
if (promise) {
$.when(promise)
.done(deferred.resolve)
.fail(deferred.reject)
.progress(deferred.notify);
}
setTimeout(function() {
deferred.reject();
}, time);
return deferred.promise();
}
这篇关于在JavaScript中,如何在超时中包装一个promise?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!