我有三个循环,所有三个可能相互依赖,也可能不依赖于所选的页面级过滤器。总共有3个过滤器
if(filter1 is selected) {
//runs first $.each loop and alters some of custom attr to DOM element
}
if(filter2 is selected) {
// Checks if filter1 was selected and are there any attr changes done by it
// runs second $.each loop and alters some of custom attr to DOM element
}
filter3 .... So on
问题是我需要知道filter1中的第一个循环是否已经完成了它的任务,然后只运行第二个过滤循环,这样我就可以完全完成filter1所做的所有attr
更改。所以我试图用户使用Deferred对象.Below是我的代码。
var defer = $.Deferred();
if(filter1) {
$.each()
.promise
.done(function(){
defer.resolve();
return defer.promise()
});
}
// same goes for filter2 and filter3
现在我想要选择filter1 [执行循环并返回承诺]或 未选择[返回承诺],然后进入同一进程的第二个过滤器。如何实现它,我怎么知道所有3个循环都已完成执行。 注意:上述过程中根本没有ajax调用。
答案 0 :(得分:2)
使用$.when
进行汇总和then
链接。
function handleFirstFilter(){
if(firstFilterSelected){
var ps = [];
$.each(elements, function(el){
ps.push(el.animate(...).promise()); // add all the promises
});
return $.when.apply($, ps); // aggregate over them
}
return $.Deferred().resolve(); // return an empty promise resolved, nothing to do
}
// the other two filters are similar in pattern, can extract it to a function
// now execute them all with each stage waiting for the previous.
handleFirstFilter().then(handleSecondFilter).then(handleThirdFilter)
答案 1 :(得分:2)
如果您的阶段仅依赖于前一阶段的完成(而非数据),并且三个过滤处理程序的区别仅在于:
然后你可以写一个通用的handleFilter()
函数,就像:
function handleFilter(selected, asyncFn) {
// return an aggregated promise or null.
return selected ? $.when.apply(null, $.map(this, asyncFn)) : null;
}
如上所述,必须使用handleFilter()
,.bind()
或.apply()
调用.call()
才能确定this
的值。
然后,您将使用handleFilter.bind()
制作三个可执行文件,每个过滤器一个,并将它们传递给.then()链以进行串行执行。
$.when()
.then(handleFilter.bind(elements_1, firstFilterSelected, asyncFn_1))
.then(handleFilter.bind(elements_2, secondFilterSelected, asyncFn_2))
.then(handleFilter.bind(elements_3, thirdFilterSelected, asyncFn_3))
.then(function() {
//everything complete
});
每个阶段都会等待前一个阶段完成。
答案 2 :(得分:0)
"将一些自定义attr改为DOM元素"
不是异步操作(如超时,ajax请求或用户交互)。当循环结束时,它将被执行并完成执行。可以从第二个循环中观察所有新属性值。
您不需要承诺,只需按顺序放置同步语句,然后按顺序对其进行评估。