关于如何使用Jquery.deferred来生成慢速同步函数的快速问题会返回一个promise。 到目前为止我所做的是:
function sayIt(ms) {
setTimeout( function() { console.log('what I say'); }, ms);
}
function doIt() {
return $.Deferred( function() { sayIt(2000); }).promise();
}
doIt().then( function() { console.log('ah'); });
sayIt(2000)总是通过,但'then'之后的链式函数永远不会触发。
如果我这样做:
doIt().then( console.log('ah'));
'啊'马上出现,然后'我说'2000ms之后 - 我想要的当然是相反的 - 两秒后我得到'我说的'然后'啊'之后
任何建议都赞赏!
答案 0 :(得分:10)
要同步做某事,但仍然使用承诺,请执行:
function slowPromise() {
var def = $.Deferred();
// do something slow and synchronous
...
// resolve the deferred with the result of the slow process
def.resolve(res);
// and return the deferred
return def.promise();
}
结果是你仍然得到了一个承诺,但是这个承诺已经解决了,所以随后在其上注册的任何.then()
都会立即进行。
这种模式的优点是,如果随后用异步代替同步代码,该函数仍具有相同的外部接口。
答案 1 :(得分:3)
如果要在超时到期后执行函数,则需要在超时到期函数内调用resolve()
对象上的Deferred
:
function sayIt(ms) {
var d = $.Deferred();
setTimeout(function() {
console.log('what I say');
d.resolve()
}, ms);
return d;
}
通过这种方式,您可以将Deferred
对象的分辨率限制为超时到期。
为了达到我认为你的意图:
function doIt() {
return sayIt(2000).promise()
}
.promise()
来电是可选的。它仅限制调用者的可用接口:通过返回Promise
而不是原始Deferred
对象,调用者只能对事件做出反应,但不会触发它们。参考:http://api.jquery.com/deferred.promise/。
最后,您的原始电话:
doIt().then( function() { console.log('ah'); });
将输出:
// 2 seconds delay
what I say
ah