В Javascript есть синхронные и асинхронные функции.
Синхронные функции
Большинство функций в Javascript являются синхронными. Если бы вы должны были вызвать несколько синхронных функций подряд
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
они выполнят по порядку. doSomethingElse
не начнется, пока doSomething
не завершится. doSomethingUsefulThisTime
, в свою очередь, не запустится, пока doSomethingElse
не завершится.
Асинхронные функции
Асинхронная функция, однако, не будет ждать друг друга. Давайте посмотрим на тот же пример кода, который мы имели выше, на этот раз, предполагая, что функции асинхронны
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
Функции будут инициализированы по порядку, но все они будут выполняться примерно одновременно. Вы не можете однозначно предсказать, какой из них закончится первым: тот, который занимает меньше всего времени для выполнения, закончится первым.
Но иногда вы хотите, чтобы функции, которые были асинхронными, выполнялись по порядку, а иногда вы хотите, чтобы функции, которые были синхронными, выполнялись асинхронно. К счастью, это возможно с обратными вызовами и таймаутами, соответственно.
Callbacks
Давайте предположим , что у нас есть три асинхронных функций , которые мы хотим выполнить в порядке, 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);
Это, однако, немного некрасиво и нарушает принцип СУХОГО [wikipedia] . Мы могли бы немного это исправить, создав функцию, которая принимает массив функций и время ожидания.
function executeAsynchronously(functions, timeout) {
for(var i = 0; i < functions.length; i++) {
setTimeout(functions[i], timeout);
}
}
Это можно назвать так:
executeAsynchronously(
[doSomething, doSomethingElse, doSomethingUsefulThisTime], 10);
Таким образом, если у вас есть асинхронные функции, которые вы хотите выполнять синхронно, используйте обратные вызовы, и если у вас есть синхронные функции, которые вы хотите выполнять асинхронно, используйте тайм-ауты.