... как я сделать это без наклеивания в SetTimeout?
Вы можете использовать web workers для долгосрочного сложного кода, в котором вы не хотите возвращаться в браузер. Этот код не может напрямую изменять DOM, но он может отправлять сообщения обратно на главный сценарий, рассказывая основному скрипту, что нужно изменить.
В браузерах, которые не поддерживают веб-работников, у вас в принципе нет выбора, кроме как вернуть (setTimeout
и его двоюродных братьев).
В Интернете вы можете найти различные примеры веб-работников, но для чего это стоит, вот что я сделал for another answer here, который показывает прогресс подсчета на большое количество. Но концепция такая же: длительный скрипт работает отдельно от основного потока JavaScript и отправляет ему обновления через postMessage
.
основного документа и сценария:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Progress</title>
<style type="text/css">
body, html {
height: 100%;
}
body {
font-family: sans-serif;
}
</style>
</head>
<body>
<div id="progress"><em>(Click to start)</em></div>
<script>
(function() {
var div = document.getElementById("progress");
var counter = new Worker("counter.js");
div.addEventListener("click", run);
counter.addEventListener("message", function(event) {
div.innerHTML = "Counter so far: " + event.data.counter;
});
function run() {
div.removeEventListener("click", run);
counter.postMessage({ max: 10000000 });
}
})();
</script>
</body>
</html>
counter.js
веб-рабочий сценарий (они всегда отдельные файлы):
self.addEventListener("message", function(event) {
var max;
var counter;
max = event.data && event.data.max || 100000;
for (counter = 0; counter < max; ++counter) {
if (counter % 1000 === 0) {
self.postMessage({counter: counter});
}
}
self.postMessage({counter: counter});
});
Я бы дал вашей функции успеха имя и переместил его из команды ajax. вы затем разбиваете разделы кода внутри функции на более именованные функции. вы можете легко вызвать эти подразделы друг от друга, используя setTimeout, если/при необходимости. внешняя функция предоставляет псевдо-глобальную переменную namepace, которая в сочетании с закрытием от подфункций упрощает управление состоянием через асинхронный поток без сложной вложенности, обычно связанной с обратными вызовами. – dandavis