#javascript #jquery #asynchronous
#javascript #jquery #асинхронный
Вопрос:
Например, допустим, я использую метод .addClass() . Вы не можете добавить к ней обратный вызов (например, вы не можете выполнить $ (‘…’).addClass(‘…’).load(‘…’)).
В большинстве случаев вы можете просто вызывать свои функции последовательно перед использованием .load(), и все в порядке.
Но что, если у меня очень медленный компьютер, где использование .addClass() занимает 5 секунд? Как мне выполнить другую асинхронную функцию только после завершения .addClass() или, если уж на то пошло, после завершения любой асинхронной функции JavaScript?
РЕДАКТИРОВАТЬ: я был неправ, .addClass не асинхронен.
Итак, тогда, на всякий случай:
$('foo').addClass('');
/*this code here will not execute UNLESS the previous line is absolutely finished?*/
Комментарии:
1. Что заставляет вас думать, что это
addClass()
асинхронно? AFAIK ни один из методов манипулирования DOM не является.2. @deceze Нет, вы правы. Установка css или класса элемента DOM — это не то, что происходит асинхронно.
Ответ №1:
addClass
не является асинхронным, и нет среды, в которой для выполнения ее работы потребуется сколько-нибудь значительное время. Различные операции jQuery, которые являются асинхронными (ajax, эффекты и тому подобное), принимают обратные вызовы как часть своего API.
Я думаю (не возвращаясь назад и не перечитывая API), что если функция API не имеет обратного вызова, вы можете предположить, что операция синхронна.
Обратное неверно; в jQuery есть несколько функций API ( each
, например), которые принимают обратные вызовы, которые не являются асинхронными, просто обратный вызов удобен по другим причинам.
В любом случае, любая асинхронная операция должна быть четко определена как таковая в документации.
Обновление: Решение вашего обновленного вопроса: Правильно, код после addClass
не будет выполняться до addClass
завершения. Даже если это заняло секунду или две (чего, конечно, не происходит, но давайте притворимся), addClass
выполнит свое дело и вернется обратно к вашему коду. Последующий код не будет выполняться до тех пор, пока это не произойдет, и никакой другой код не может выполняться, пока это происходит (поскольку JavaScript в веб-браузерах является однопоточным, если вы не используете web workers, и даже тогда координация между потоками является явной).
Есть некоторые операции, при которых вы должны дать браузеру время обработать то, что вы сказали ему сделать. Я пытаюсь придумать конкретный пример, что-то вроде добавления полей формы в IE. Определенно, не простые вещи. В таких редких ситуациях вы можете убедиться, что предоставили браузеру возможность выполнить свое задание, явно уступив браузеру с помощью setTimeout
:
doSomethingTheBrowserHasToThinkAbout();
setTimeout(function() {
// Now you know the browser's had time to think about it
doSomethingElse();
}, 0); // <== Won't really be 0, most browsers clamp this to 5-10ms minimum
Но вам не обязательно это делать (и вы не хотите этого делать), за исключением определенных операций. Извините, я не сразу вспоминаю пример, но здесь мы говорим о крайних случаях.
Комментарии:
1. Спасибо за разъяснение. Таким образом, абсолютно ничего не будет выполняться после .addClass до завершения .addClass, даже если мой компьютер 70-х годов и это занимает 5 секунд? (обновленный исходный вопрос)
2. @trusktr: Нет.
addClass
завершит выполнение своей задачи и вернется обратно к вашему коду. Никакой другой код не может выполняться, пока это происходит (потому что JavaScript в веб-браузерах является однопоточным, если вы не используете web workers , и даже тогда координация между потоками является явной).3. Просто хотел сказать спасибо за добавление дополнительной информации внизу в этом примере функции. У меня была одна из таких редких ситуаций, и я потратил больше дня времени, пытаясь выяснить, как это исправить. Я ценю дополнительную информацию!
Ответ №2:
addClass не завершается для меня, пока я не добавлю последующий ajax / рендеринг в setTimeout. Она должна быть в некоторой степени асинхронной. Я пытаюсь добавить класс в тело (для загрузки gif), и он просто добавляет атрибут «class» без значения. Когда код after помещается в setTimeout , он завершается. Это в Chrome и почти 4 года спустя…
Ответ №3:
addClass
не является асинхронным. В jQuery асинхронные методы позволяют вам указать функцию обратного вызова, которая будет вызвана после завершения метода. Если нет сигнатуры метода, который принимает обратный вызов, то, скорее всего, этот метод является синхронным.