延迟jquery承诺 [英] delay for jquery promises
问题描述
我找不到延迟
或等待
函数
jQuery
承诺。我在SO上找到了一个函数(使用jQuery.Deferred以避免嵌套的setTimeout回调):
I cannot find delay
or wait
function for jQuery
promises. I have found one function on the SO (Using jQuery.Deferred to avoid nested setTimeout callbacks):
function delay(time) {
return function () {
console.log("Delaying");
var ret = new $.Deferred();
setTimeout(function () {
ret.resolve();
}, time);
return ret;
};
}
而且,这就是我使用它的方式:
And, it's the way how I use it:
run: function () {
return $()
.promise()
.then(function () {
console.log("call together");
console.log("call together");
})
.then(delay(2000))
.then(function () {
console.log("call first");
})
.then(delay(2000))
.then(function () {
console.log("call second");
})
}
我想扩展我可以编写的promise或deferred对象:
I want to extend promise or deferred object that I can write like:
run: function () {
return $()
.promise()
.then(function () {
console.log("call together");
console.log("call together");
})
.delay(2000)
.then(function () {
console.log("call first");
})
.delay(2000)
.then(function () {
console.log("call second");
})
}
推荐答案
因为@Bergi说jQuery Deferreds / Promises不是可以通过原型继承扩展。
As @Bergi says jQuery Deferreds/Promises are not extendible by prototypal inheritance.
相反,jQuery采用的模型是允许使用语法扩展单个Promise实例:
Instead, the model adopted by jQuery is to allow individual Promise instances to be extended with the syntax :
deferred.promise(target);
//or,
promise.promise(target); //(though the documentation doesn't make this clear)
// where `target` is an "object onto which the promise methods have to be attached"
// see https://api.jquery.com/deferred.promise/
通过使用一堆方法定义构造函数,任何jQuery延迟或者Promise可以使用简单的语法扩展
By defining a constructor with a bunch of methods, any jQuery Deferred or Promise can be extended with the simple syntax
.promise(Constructor())
在我未发表的未记录的jQuery promises Playground中,构造函数名为 $ P
并保存在jQuery命名空间,因此我使用的实际语法是:
In my unpublished, undocumented jQuery promises Playground, the constructor is named $P
and kept in the jQuery namespace, hence the actual syntax I use is :
.promise($.$P())
你需要注意的是,在大多数情况下,没有必要调用 $ 。$ P()
显式为Playground包含 $。当_()
方法返回已经扩展的Promise。
You need to be aware of that, for the most part, it's not necessary to call $.$P()
explicitly as the Playground includes a $.when_()
method that returns an already extended Promise.
这是Playground的缩写版本,足以提供 .delay()
方法:
Here's an abbreviated version of the Playground with just enough to provide a .delay()
method :
(function($) {
/* ***********************************
* The $.$P function returns an object
* designed to be extended with
* promise methods using the syntax :
* myDeferred.promise($.$P())
* myPromise.promise($.$P())
* where `myDeferred`/`myPromise`
* are jQuery Deferred/Promise objects.
* ***********************************/
/* ***********************************
* Methods
* ***********************************/
$.$P = function() {
if (this instanceof $.$P) {
return this;
} else {
return new $.$P();
}
};
$.$P.prototype.then_ = function(fa, fb) {
/* A promise method that is the same as .then()
* but makes these extra methods available
* down-chain.
*/
return this.then(fa||null, fb||null).promise($.$P());
}
$.$P.prototype.delay_ = function(ms) {
/* A promise method that
* introduces a down-chain delay.
*/
var promise = this;
function f(method) {
return function() { setTimeout(function(){ method.apply(null,this); }.bind(arguments), ms||0); };
}
return $.Deferred(function(dfrd) {
promise.then(f(dfrd.resolve), f(dfrd.reject));
}).promise($.$P());
}
/* ***********************************
* Utility functions
* ***********************************/
function consolidate(args) {
/* Convert mixed promises/arrays_of_promises to single array.
* Called by all the when_() methods below.
*/
return Array.prototype.slice.apply(args).reduce(function(arr, current) {
return arr.concat(current);
}, []);
}
/* ***********************************
* This section extends the jQuery namespace
* with a "jQuery.when_()" method.
* ***********************************
*/
$.extend({
'when_': function() {
return $.when.apply(null, consolidate(arguments)).promise($.$P()).then_(function() {
return consolidate(arguments);
});
},
});
})(jQuery);
完整的Playground还包含一大堆更多静态和promise-instance方法用于其他目的,开发它们是该剧的精髓。
使用Playgound的基本规则如下:
The ground-rules for using the Playgound are as follows :
- 所有Playground的静态和promise方法都以_下划线结尾。
- 静态方法,例如
$。当_()
,只需安装Playgound即可使用。 - 承诺链中的承诺通过包含静态方法来扩展,例如
.when _()
,或链接.promise($。$ P())
。 - 在承诺链中,通过使用..._方法而不是标准,扩展仍然可用(在链中)方法,例如
.then _()
代替.then()
。
- All the Playground's static and promise methods end in "_" underscore.
- Static methods, eg
$.when_()
, are made available just by installing the Playgound. - Promises in a promise chain are extended by including a static method, eg
.when_()
, or chaining.promise($.$P())
. - In a promise chain, the extensions remain available (down the chain) by using "..._" methods rather than the standard methods, eg
.then_()
in place of.then()
.
所以这里是如何使用它来强加问题所需的延迟:
So here's how to use it to impose the delays required by the question :
jQuery(function($) {
var MYNAMESPACE = {
run: function (t) {
return $.when_()
.then_(function () {
log("call together");
log("call together");
})
.delay_(t)
.then_(function () {
log("call first");
})
.delay_(t)
.then_(function () {
log("call second");
});
}
}
});
DEMO
在演示中,按钮的点击处理程序进一步说明了如何使用Playground。
In the demo, the button's click handler gives further indication of how the Playground can be used.
使用游乐场的Provisos:
Provisos on using the Playground :
- 正如我所说 - 这是一个游乐场。
- 作为jQuery的适配器,而不是补丁,它在某些地方效率极低。最糟糕的是,除了返回的方法之外,某些方法还会产生中间承诺。
- 未按生产代码中使用的标准进行测试,因此请谨慎使用。
最后,如果你决定用jQuery实现延迟,只考虑上面的内容。使用已经有 .delay()
方法的promise lib要简单得多。
And lastly, only consider the above if you are determined to implement delay with jQuery. It's far far simpler to use a promise lib that already has a .delay()
method.
这篇关于延迟jquery承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!