У Javascript є синхронні та асинхронні функції.
Синхронні функції
Більшість функцій Javascript є синхронними. Якби ви викликали кілька синхронних функцій поспіль
doSomething();
doSomethingElse();
doSomethingUsefulThisTime();
вони будуть виконувати по порядку. doSomethingElse
не розпочнеться, поки doSomething
не завершиться. doSomethingUsefulThisTime
, у свою чергу, не розпочнеться, поки doSomethingElse
не завершиться.
Асинхронні функції
Однак асинхронна функція не чекатиме один одного. Давайте подивимось на той самий зразок коду, який був у нас вище, цього разу припускаючи, що функції асинхронні
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);
Підсумовуючи це, якщо у вас є асинхронні функції, які ви хочете виконувати синхронно, використовуйте зворотні дзвінки, а якщо у вас є синхронні функції, які ви хочете виконувати асинхронно, використовуйте тайм-аути.