【问题标题】:javascript - execute function after for loopjavascript - 在for循环后执行函数
【发布时间】:2017-10-30 12:36:19
【问题描述】:

我有一个功能,点击按钮会从甘特图中获取所选任务的所有 id,并运行一个 for 循环来保存我使用 AJAX 请求在表单中编辑的每个所选任务。

现在关于 AJAX 请求 success 的问题我添加了一个代码来清除并再次在甘特图中加载所有数据,但它没有按预期进行,多次加载数据并开始创建相同数据的副本在我的甘特图中,我尝试在循环之外执行 gantt.load 函数,但它仍然无法正常工作。

那么如何创建一个条件,在循环完成后重新加载甘特图?非常感谢任何帮助。

下面是我的代码:

HTML

<button type="button" class="btn btn-primary" onclick="editForm()">Edit</button>

javascript

 function editForm() {
            var selected_task = gantt.getSelectedTasks();

            for (var i = 0; i < selected_task.length; i++) {
                var task = selected_task[i];
                var data = gantt.getTask(task);
                    $.ajax({
                        type: 'PUT',
                        url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
                        data: postData,
                        success: function () {
                            $('#edit_form_modal').modal('hide');
                            gantt.clearAll();
                            gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");

                        },
                        error: function (err) {
                            alert("Failed because of " + err);
                        }
                    })
            }
        }

【问题讨论】:

  • AJAX 调用是异步的,因此您不能期望同步代码 for 等待异步代码完成,因为您在代码执行时没有结果,因此您必须等待结果,我建议使用Promises 来实现它,因为它可以让您等待所有异步代码并在有结果时执行函数

标签: javascript jquery ajax


【解决方案1】:

将选定的任务映射到承诺列表,并在所有承诺解决后使用jQuery when 加载甘特图。

function editForm() {
  var selected_task = gantt.getSelectedTasks();

  var saveSelectedTask = selected_task.map(function(task, i) {
    var data = gantt.getTask(task);
    return $.ajax({
      type: 'PUT',
      url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
      data: postData,
    });
  });

  $.when(saveSelectedTask)
    .done(function() {
      $('#edit_form_modal').modal('hide');
      gantt.clearAll();
      gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");
    })
    .fail(function(err) {
      alert("Failed because of " + err);
    });
}

【讨论】:

  • 嗨@Oluwafemi 感谢您的回复,它有帮助,但刷新似乎还是有点太快,当页面完成重新加载时,一些数据还没有更新,所以添加一个@ gantt.load 上的 987654323@,它可以工作但效率不高,您对此有什么建议吗?
【解决方案2】:

在这种情况下,你应该使用Promise,确切地说是Promise.all(我建议你在实现之前去这些URL了解更多关于Promise的知识。 这个想法是让请求并行运行,然后等待所有完成并进行回调。

我会将你的 JS 重写为:

function editForm() {
         var selected_task = gantt.getSelectedTasks();
          Promise.all(selected_task.map(function(task) {
            var data = gantt.getTask(task);
            return $.ajax({
                    type: 'PUT',
                    url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
                    data: postData,
                })
        }).then(function(results) {
           $('#edit_form_modal').modal('hide');
           gantt.clearAll();
           gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");

        })
    }

更新:如果你更喜欢使用 jQuery 函数,那么你可以使用 $.when()

 function editForm() {
         var selected_task = gantt.getSelectedTasks();
          $.when(selected_task.map(function(task) {
            var data = gantt.getTask(task);
            return $.ajax({
                    type: 'PUT',
                    url: '/api/dashboard/workorder_detail/' + data.workorder_id + '/',
                    data: postData,
                })
        }).then(function(results) {
           $('#edit_form_modal').modal('hide');
           gantt.clearAll();
           gantt.load("/api/scheduler/{{ selected_project.id }}/?format=json", "json");

        })
    }

但正如我上面所说,解决问题并不会让你变得更好,应该深入挖掘并了解函数的工作原理。

【讨论】:

  • 嗨@Kai 谢谢你的回复,它有帮助,我很感激你的建议,我会在这方面研究更多,只有1件事,看起来刷新还是有点太快了,当页面完成重新加载一些数据还没有更新,所以在gantt.load上添加一个setTimeout(),它可以工作但效率不高,您对此有什么建议吗?
  • @M.Izzat 我认为您应该检查更新代码是否正常工作。也许数据被缓存了。
最近更新 更多