【问题标题】:jQuery Sequentially Execute Async EventsjQuery 顺序执行异步事件
【发布时间】:2016-07-22 04:22:16
【问题描述】:

我正在尝试使用 jQuery 编写一些 JavaScript 代码,以顺序执行一些异步事件(在循环中);仅在前一个异步事件完成后进行迭代。

基本思路是:

for (var i = 0; i < someLength; i++) {
    // 1. dynamically add a <form> and <input>s to the DOM
    // 2. submit the form to a target <iframe>
    // 3. wait for an async callback indicating the form has been submitted
}

我有 #1 和 #2 的工作代码,我可以将 load 事件侦听器附加到 &lt;iframe&gt; 以了解表单提交何时完成:

$('.iframe').on('load', function() { ...
});

for (var i = 0; i < someLength; i++) {
    // 1. dynamically add a <form> and <input>s in the DOM
    // 2. submit the form to a target <iframe>
    // 3. wait for an async callback indicating the form has been submitted
}

问题是我不知道如何将ready 回调绑定到循环逻辑。我试图研究延迟/承诺,但并没有真正了解如何在这里正确应用这些概念。

如果答案是使用 Promise,那么我也很想看看如何合并一些代码以在循环进行时显示“加载”微调器,然后在我们退出循环后移除微调器。

谢谢!

【问题讨论】:

    标签: javascript jquery asynchronous promise


    【解决方案1】:

    For-loop 不喜欢异步操作,尤其是如果您想链接它们。解决方案可能如下所示。

    $('.iframe').on('load', function() { ...
        // increment i
        //if(i >= someLength) exit
        // 1. dynamically add a <form> and <input>s in the DOM
        // 2. submit the form to a target <iframe>
    });
    
    //for (var i = 0; i < someLength; i++) {//no loop
    //}
        // 1. dynamically add a <form> and <input>s in the DOM
        // 2. submit the form to a target <iframe>
        // 3. nothing to wait
    

    【讨论】:

    • 谢谢@Alex。所以在这个解决方案中,我是否基本上将所有提交排队,然后等待load 回调触发someLength 次数?如果我只想在前一个成功的情况下进行下一个提交(假设我有办法知道它是成功还是失败)?
    • .load 处理程序中,您可以检查当前状态并决定下一步做什么。
    • 对,但我认为在您的代码中,所有提交请求都将在for 循环中启动/排队,并且load 处理程序只会在一个请求完成时被回调。使用此方案,如果前一个提交失败,您无法阻止下一个提交执行,或者我错过了什么?
    • 是的,我可以。下一次提交来自.loadhandler IIF 上一次是成功的。
    • 哦,糟糕.. 没有意识到你已经注释掉了循环。
    【解决方案2】:

    我认为你可以用递归的方式来代替 for 循环。像这样-

    $("#imgSpinner").show();
    someFunction(0,someLength);
    
    function someFunction(currentSeq,totalIterations)
    {
        $.ajax({
                url: URL,
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                success: function (result) {
                         if (currentSeq<totalIterations)
                           someFunction(currentSeq++,totalIterations);
                         else
                           $("#imgSpinner").hide();
                },
                error: function (error) {
                    //handle error
    
                }
         });
    
    }
    

    【讨论】:

    • 谢谢,但我无法使用$.ajax,因为我要发布到不同的域。理想情况下,我想要一个仍然实现承诺/延迟的解决方案,因为我想(通过示例)学习如何正确使用它们。
    【解决方案3】:

    我正在尝试了解如何使用 for 循环创建表单和字段...所有表单都包含相同的字段吗?即多个电子邮件地址或什么?

    在不了解设计的情况下,我将举个例子,提交一些数据,然后在完成提交下一个数据时。

    $.when(AjaxSubmitFirstData.call()).done(function (data) {
      $.when(AjaxSubmitSecondData.call()).done(function (data) {
        // finished
      });
    });
    
    var AjaxSubmitFirstData = {
      call: function () {
        return $.ajax({
          url: url,
          type: 'POST',
          data: "{}",
          contentType: 'application/json; charset=utf-8',
        }).done(function (data) {
        }).fail(function (jq, textStatus) {
        });
      }
    };
    
    var AjaxSubmitSecondData = {
      call: function () {
        return $.ajax({
          url: url,
          type: 'POST',
          data: "{}",
          contentType: 'application/json; charset=utf-8',
        }).done(function (data) {
        }).fail(function (jq, textStatus) {
        });
      }
    };
    

    【讨论】:

    • 谢谢。我需要创建多个表单的原因是因为我将多个 POST 发送到不同的域(每个请求中的数据不同),因此不能使用 AJAX(因为同源策略)。您是否可以修改您的答案以显示在不使用$.ajax 时如何使用延迟?
    猜你喜欢
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多