【发布时间】:2014-08-02 17:22:36
【问题描述】:
使用 defered/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 的异步函数并处理超时:
// 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 函数以便它可以接受返回承诺的函数而不会丢失它们的错误/进度信息?
【问题讨论】:
-
您的原语是错误的,您需要分两个阶段对其进行承诺,首先 - 承诺 superImportantLibrary.doSomething 方法,然后才执行承诺返回。另外,请避免使用 jQuery 承诺,与其他实现相比,它们很糟糕。
-
@BenjaminGruenbaum - 哪些实现?为什么 jQuery 的 promise 很可怕?你说'你的原语是错误的'是什么意思?如果它是库而不是我自己的代码,我如何“承诺”
superImportantLibrary.doSomething,你能写一些示例代码来解释你的意思吗? -
我担心我无法在没有证明自己的情况下做出这样的声明:) 所以this is how to convert an API to promises(转换库本身)、this is why jQuery deferreds are bad 和as explained by domenic,至于图书馆,我会使用Bluebird
-
@BenjaminGruenbaum - 所以
myFunc是一种承诺superImportantLibrary.doSomething方法的方法。它只返回一个承诺。为什么说是错的?我仍然会很感激一些代码来解释你将如何以正确的方式做到这一点。感谢其他链接! -
我已经添加了一个答案,如果您不确定任何事情,请随时要求澄清。
标签: javascript jquery promise jquery-deferred deferred