В Javascript есть синхронные и асинхронные функции.
Синхронные функции
Большинство функций в Javascript являются синхронными.Если вам нужно было вызвать несколько синхронных функций подряд
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
, они будут выполняться по порядку.doSomethingElse
не запустится, пока не завершится doSomething
.doSomethingUsefulThisTime
, в свою очередь, не запустится, пока не завершится * 1015. *
Асинхронные функции
Однако асинхронная функция не будет ждать друг друга.Давайте посмотрим на тот же пример кода, который мы имели выше, на этот раз, предполагая, что функции асинхронны
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
Функции будут инициализированы по порядку, но все они будут выполняться примерно в одно и то же время.Вы не можете однозначно предсказать, какой из них закончится первым: тот, который занимает наименьшее количество времени для выполнения, закончится первым.
Но иногда вы хотите, чтобы функции, выполняемые асинхронно, выполнялись по порядку, ииногда вы хотите, чтобы синхронные функции выполнялись асинхронно.К счастью, это возможно с обратными вызовами и тайм-аутами соответственно.
Обратные вызовы
Предположим, что у нас есть три асинхронные функции, которые мы хотим выполнить по порядку, some_3secs_function
, some_5secs_function
иsome_8secs_function
.
Поскольку функции могут быть переданы в качестве аргументов в Javascript, вы можете передать функцию в качестве функции обратного вызова для выполнения после завершения функции.
Если мы создаем функции, подобные этой
function some_3secs_function(value, callback){
//do stuff
callback();
}
затем вы можете вызвать затем по порядку, например так:
some_3secs_function(some_value, function() {
some_5secs_function(other_value, function() {
some_8secs_function(third_value, function() {
//All three functions have completed, in order.
});
});
});
Таймауты
В Javascript вы можете указать, что функция должна выполняться после определенного тайм-аута (в миллисекундах).По сути, это может заставить асинхронные функции вести себя асинхронно.
Если у нас есть три синхронные функции, мы можем выполнять их асинхронно, используя функцию setTimeout
.
setTimeout(doSomething, 10);
setTimeout(doSomethingElse, 10);
setTimeout(doSomethingUsefulThisTime, 10);
Это, однако,, немного некрасиво и нарушает принцип DRY [wikipedia] .Мы могли бы немного это исправить, создав функцию, которая принимает массив функций и время ожидания.
function executeAsynchronously(functions, timeout) {
for(var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
Это можно назвать так:
executeAsynchronously(
[doSomething, doSomethingElse, doSomethingUsefulThisTime], 10);
В итоге, если у вас есть асинхронные функции, которые вы хотите выполнять синхронно, используйте обратные вызовы, и если у вас есть синхронные функции, которыеВы хотите выполнить асинхронно, используйте тайм-ауты.