Как вы определяете, завершена ли асинхронная функция в перед выполнением другой в jQuery (на действительно медленных компьютерах)?

#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 асинхронные методы позволяют вам указать функцию обратного вызова, которая будет вызвана после завершения метода. Если нет сигнатуры метода, который принимает обратный вызов, то, скорее всего, этот метод является синхронным.