Во-первых, нам нужно исправить ошибки в функции uploadSteps
:
function uploadSteps(maxStep) {
// here change `var x` to `let x` to avoid problems
// like here - https://stackoverflow.com/q/750486/5811984
for (let x = 1; x <= maxStep; x++){
setTimeout(function() {
// notice how here ajaxFetch(x) is wrapped into a function,
// otherwise it gets called right away
ajaxFetch(x)
}, 20);
}
}
Теперь вот еще одна проблема - все setTimeout будут вызываться с задержкой 20ms
, то есть все они будутбудет выполняться одновременно, но через ~ 20 мс после вызова uploadSteps()
.
Давайте посмотрим, что произойдет, когда maxStep=3
(при условии, что ваш процессор очень быстрый, потому что это не имеет значения для понимания проблемы):
Time passed | what happens
--------------------------
0ms | setTimeout(ajaxFetch(1), 20) is called
0ms | setTimeout(ajaxFetch(2), 20) is called
0ms | setTimeout(ajaxFetch(3), 20) is called
20ms | ajaxFetch(1) is called
20ms | ajaxFetch(2) is called
20ms | ajaxFetch(3) is called
Итак, как вы видите, все ajaxFetch
вызываются одновременно, и я предполагаю, что это не совсем то, что вам нужно.То, что вы можете искать, это:
Time passed | what happens
--------------------------
0ms | setTimeout(ajaxFetch(1), 20) is called
0ms | setTimeout(ajaxFetch(2), 40) is called
0ms | setTimeout(ajaxFetch(3), 60) is called
20ms | ajaxFetch(1) is called
40ms | ajaxFetch(2) is called
60ms | ajaxFetch(3) is called
, который может быть реализован с небольшим изменением вашего кода
function uploadSteps(maxStep) {
for (let x = 1; x <= maxStep; x++){
setTimeout(function() {
ajaxFetch(x)
}, 20 * x); // change delay from 20 -> 20 * x
}
}
Кроме того, похоже, вам не нужно ничего возвращатьс ajaxFetch()
, поэтому лучше сделать его асинхронным, чтобы он не блокировал выполнение кода:
function ajaxFetch(s) {
$.ajax({
type: "POST",
url: "post.php",
data: {
step: s
},
// async: false, -- remove this, it's true by default
dataType: 'JSON',
success: function (response) {
$("#loadText").text(response.stepText);
console.log(response.stepText);
}
});
}
Даже если на самом деле do нужно что-то вернуть для fetchAjax()
,лучше держать его асинхронным и использовать обратные вызовы / обещания. jQuery на самом деле настоятельно не рекомендует использовать async: false
в любом случае.
Если причина, по которой вы добавили setTimeout
s, заключается в том, чтобы убедиться, что все шаги выполнены по порядку, то этоне правильный способ сделать это.Проблемы:
- Допустим, серверу потребовалось 100 мс для ответа на первый запрос и 10 мс для второго.Даже с задержкой в 20 мсек второй запрос будет выполнен первым.И просто увеличение задержки не является решением, потому что:
- Если ваш сервер реагирует намного быстрее, вы вводите ненужное ожидание для пользователя.
Лучше добавитьобратный вызов из ajaxFetch()
, который будет вызван, когда будет выполнена выборка ajax, а затем вы позвоните в следующий ajaxFetch()
после получения обратного вызова.