Javascript 在jQuery中使用多个$each循环

Javascript 在jQuery中使用多个$each循环,javascript,jquery,promise,jquery-deferred,deferred,Javascript,Jquery,Promise,Jquery Deferred,Deferred,每个循环有三个循环,根据所选的页面级筛选器,所有三个循环可能相互依赖,也可能不相互依赖。总共有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

每个循环有三个循环,根据所选的页面级筛选器,所有三个循环可能相互依赖,也可能不相互依赖。总共有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中的第一个循环是否完成了它的任务,然后只运行第二个filter循环,这样我就可以让filter1完美地完成所有
attr
更改。所以我尝试使用延迟对象。下面是我的代码

var defer = $.Deferred();
if(filter1) {
  $.each()
    .promise
    .done(function(){
      defer.resolve();
      return defer.promise()
    });
}

// same goes for filter2 and filter3
现在我想知道filter1是否被选中[执行循环并返回承诺]或 未选择[return promise],然后按照相同的过程进入第二个过滤器。我如何实现它,以及我如何知道所有3个循环都已完成执行。
注意:上述过程中根本没有ajax调用。

使用
$。当
用于聚合和
时,则使用
链接

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)

使用
$。当
用于聚合时,然后使用
链接

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)

如果您的阶段仅依赖于前一阶段的完成(而不是来自前一阶段的数据),并且三个过滤器处理程序的不同之处仅在于:

  • 一种特殊的布尔状态
  • 这些因素起了作用
  • 应用于每个元素的asycn功能
然后,您可以编写一个通用的
handleFilter()
函数,如下所示:

function handleFilter(selected, asyncFn) {
    // return an aggregated promise or null.
    return selected ? $.when.apply(null, $.map(this, asyncFn)) : null;
}
如前所述,必须使用
.bind()
.apply()
.call()
调用
handleFilter()
,以建立
的值

然后使用
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
    });

每个阶段将等待前一个阶段完成。

如果您的阶段仅依赖于前一个阶段的完成(而不是来自前一个阶段的数据),并且三个筛选器处理程序的不同之处仅在于:

  • 一种特殊的布尔状态
  • 这些因素起了作用
  • 应用于每个元素的asycn功能
然后,您可以编写一个通用的
handleFilter()
函数,如下所示:

function handleFilter(selected, asyncFn) {
    // return an aggregated promise or null.
    return selected ? $.when.apply(null, $.map(this, asyncFn)) : null;
}
如前所述,必须使用
.bind()
.apply()
.call()
调用
handleFilter()
,以建立
的值

然后使用
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
    });
每个阶段将等待前一个阶段完成

“将某些自定义属性更改为DOM元素”

不是异步操作(如超时、ajax请求或用户交互)。当循环结束时,它将被执行并完成执行。所有新的属性值都可以从第二个循环中观察到

您不需要承诺在这里,只需将同步语句按正确的顺序排列,它们将按顺序进行计算

“将某些自定义属性更改为DOM元素”

不是异步操作(如超时、ajax请求或用户交互)。当循环结束时,它将被执行并完成执行。所有新的属性值都可以从第二个循环中观察到


您不需要承诺在这里,只需将同步语句按正确的顺序排列,它们将按顺序进行计算。

filter1操作的性质是不明确的。总的来说,这个问题意味着异步,但描述“将一些自定义attr更改为DOM元素”意味着同步。@Roamer是的,你是对的,那么让我们假设它们是异步的。“filter1”操作的性质是不明确的。总的来说,这个问题意味着异步,但描述“将一些自定义attr更改为DOM元素”暗示同步。@Roamer是的,你是对的,那么让我们假设它们是异步的。我怎么知道所有then语句都已完成执行我怎么知道所有then语句都已完成执行谢谢我使用了你的想法,但修改了一点,比如callfunction1()。然后(function(){callfunction2()。然后(function(){callfunction3()。然后(function(){console.log(“I am Done”)}});但在上面的代码中,我该如何处理,比如说如果callfunction2()失败,或者换句话说,如何知道某个特定函数失败“…一点…”!我的想法还存在吗?我省略了故障处理,因为这不在问题中。如何处理错误取决于所需的行为。有两个基本选项-失败时停止或失败时继续。谢谢,我使用了你的想法,但修改了一点,比如callfunction1()。然后(function(){callfunction2()。然后(function(){callfunction3()。然后(function(){console.log(“I am Done”)}});但在上面的代码中,我该如何处理,比如说如果callfunction2()失败,或者换句话说,如何知道某个特定函数失败“…一点…”!我的想法还存在吗?我忽略了故障处理,因为它不在问题中。如何处理错误取决于所需的行为。有两个基本选项-故障时停止或故障时继续。