Если мне нужно вызвать эту функцию одну за другой,
$('#art1').animate({'width':'1000px'},1000);
$('#art2').animate({'width':'1000px'},1000);
$('#art3').animate({'width':'1000px'},1000);
Я знаю, в jQuery я мог бы сделать что-то вроде:
$('#art1').animate({'width':'1000px'},1000,'linear',function(){
$('#art2').animate({'width':'1000px'},1000,'linear',function(){
$('#art3').animate({'width':'1000px'},1000);
});
});
Но давайте предположим, что я не использую jQuery и хочу позвонить:
some_3secs_function(some_value);
some_5secs_function(some_value);
some_8secs_function(some_value);
Как я должен вызывать эту функцию для выполнения some_3secs_function
, и ПОСЛЕ того, что вызов заканчивается, затем выполнить some_5secs_function
и ПОСЛЕ того, что вызов заканчивается, затем вызывать some_8secs_function
?
ОБНОВИТЬ:
Это все еще не работает:
(function(callback){
$('#art1').animate({'width':'1000px'},1000);
callback();
})((function(callback2){
$('#art2').animate({'width':'1000px'},1000);
callback2();
})(function(){
$('#art3').animate({'width':'1000px'},1000);
}));
Три анимации начинаются одновременно
Где моя ошибка?
Ответы:
В Javascript есть синхронные и асинхронные функции.
Синхронные функции
Большинство функций в Javascript являются синхронными. Если бы вы должны были вызвать несколько синхронных функций подряд
они выполнят по порядку.
doSomethingElse
не начнется, покаdoSomething
не завершится.doSomethingUsefulThisTime
, в свою очередь, не запустится, покаdoSomethingElse
не завершится.Асинхронные функции
Асинхронная функция, однако, не будет ждать друг друга. Давайте посмотрим на тот же пример кода, который мы имели выше, на этот раз, предполагая, что функции асинхронны
Функции будут инициализированы по порядку, но все они будут выполняться примерно одновременно. Вы не можете однозначно предсказать, какой из них закончится первым: тот, который занимает меньше всего времени для выполнения, закончится первым.
Но иногда вы хотите, чтобы функции, которые были асинхронными, выполнялись по порядку, а иногда вы хотите, чтобы функции, которые были синхронными, выполнялись асинхронно. К счастью, это возможно с обратными вызовами и таймаутами, соответственно.
Callbacks
Давайте предположим , что у нас есть три асинхронных функций , которые мы хотим выполнить в порядке,
some_3secs_function
,some_5secs_function
, иsome_8secs_function
.Так как функции могут быть переданы в качестве аргументов в Javascript, вы можете передать функцию в качестве обратного вызова для выполнения после завершения функции.
Если мы создадим такие функции, как это
тогда вы можете позвонить тогда по порядку, вот так:
Таймауты
В Javascript вы можете указать функции для выполнения после определенного времени ожидания (в миллисекундах). Это может, по сути, заставить синхронные функции вести себя асинхронно.
Если у нас есть три синхронные функции, мы можем выполнять их асинхронно, используя
setTimeout
функцию.Это, однако, немного некрасиво и нарушает принцип СУХОГО [wikipedia] . Мы могли бы немного это исправить, создав функцию, которая принимает массив функций и время ожидания.
Это можно назвать так:
Таким образом, если у вас есть асинхронные функции, которые вы хотите выполнять синхронно, используйте обратные вызовы, и если у вас есть синхронные функции, которые вы хотите выполнять асинхронно, используйте тайм-ауты.
источник
Этот ответ использует
promises
функциюECMAScript 6
стандарта JavaScript . Если ваша целевая платформа не поддерживаетpromises
, заполните ее с помощью PromiseJs .Посмотрите на мой ответ здесь. Дождитесь завершения функции с анимацией, пока не запустите другую функцию, если хотите использовать
jQuery
анимацию.Вот как будет выглядеть ваш код с
ES6 Promises
иjQuery animations
.Нормальные методы также могут быть включены
Promises
.then
Метод выполняется , как толькоPromise
завершена. Обычно возвращаемое значениеfunction
переданного вthen
передается следующему как результат.Но если
Promise
возвращается a , следующаяthen
функция ожидаетPromise
завершения выполнения и получает результаты (значение, которое передаетсяfulfill
).источник
Похоже, вы не до конца понимаете разницу между синхронным и асинхронным выполнением функций.
Код, который вы указали в своем обновлении, немедленно выполняет все функции обратного вызова, которые, в свою очередь, немедленно запускают анимацию. Анимация, однако, выполняется асинхронно . Это работает так:
setTimeout
с функцией, содержащей следующий шаг анимации и задержкуsetTimeout
ИсполняетЭто продолжается до тех пор, пока не завершится последний шаг анимации. Тем временем ваши синхронные функции давно завершены. Другими словами, ваш вызов
animate
функции на самом деле не занимает 3 секунды. Эффект моделируется с задержками и обратными вызовами.Что вам нужно, это очередь . Внутри jQuery ставит в очередь анимации, выполняя ваш обратный вызов только после завершения соответствующей анимации. Если ваш обратный вызов затем запускает другую анимацию, эффект состоит в том, что они выполняются последовательно.
В простейшем случае это эквивалентно следующему:
Вот общая функция асинхронного зацикливания. Он будет вызывать заданные функции по порядку, ожидая указанное количество секунд между ними.
Использование:
Очевидно, вы можете изменить это, чтобы принимать настраиваемое время ожидания или немедленно выполнять первую функцию или прекратить выполнение, когда функция в цепочке возвращается
false
или кapply
функциям в указанном контексте, или к чему-либо еще, что вам может понадобиться.источник
Я полагаю, что асинхронная библиотека предоставит вам очень элегантный способ сделать это. В то время как обещания и обратные вызовы могут быть немного сложными для манипулирования, асинхронность может дать аккуратные шаблоны для оптимизации вашего мыслительного процесса. Чтобы запустить функции в последовательном режиме, вам нужно поместить их в асинхронный водопад . В асинхронном жаргоне каждая функция называется a,
task
которая принимает некоторые аргументы, и acallback
; которая является следующей функцией в последовательности. Базовая структура будет выглядеть примерно так:Я просто попытался кратко объяснить структуру здесь. Прочитайте водопад руководство для получения дополнительной информации, это очень хорошо написано.
источник
ваши функции должны принимать функцию обратного вызова, которая вызывается по завершении.
тогда использование будет выглядеть так:
источник
Я не буду углубляться в обсуждение setTimeout здесь, но:
источник
Поскольку вы пометили его с помощью javascript, я бы использовал элемент управления таймером, поскольку ваши имена функций составляют 3, 5 и 8 секунд. Итак, запустите таймер, 3 секунды, вызовите первую, 5 секунд - вызов второй, 8 секунд - третий, затем, когда все будет сделано, остановите таймер.
Обычно в Javascript то, что у вас есть, правильно, потому что функции выполняются одна за другой, но так как похоже, что вы пытаетесь сделать синхронизированную анимацию, таймер будет лучшим выбором.
источник
источник
next
?Вы также можете использовать обещания следующим образом:
Вы должны сделать
some_value
глобальный, чтобы получить доступ к нему из .thenВ качестве альтернативы, из внешней функции вы можете вернуть значение, которое будет использовать внутренняя функция, например:
источник
Я использую функцию «waitUntil», основанную на setTimeout javascript
Это будет прекрасно работать, если ваши функции установят для определенного условия значение true, которое вы сможете опрашивать. Кроме того, он поставляется с тайм-аутами, которые предлагают вам альтернативы в случае, если ваша функция не смогла что-то сделать (даже в пределах временного диапазона. Подумайте об обратной связи с пользователем!)
например
источник
Если метод 1 должен быть выполнен после метода 2, 3, 4. Следующий фрагмент кода может быть решением для этого с использованием отложенного объекта в JavaScript.
источник