Как код Javascript становится асинхронным при использовании обратных вызовов?

26

Я много читал в Интернете, пытаясь понять, как писать асинхронный код JavaScript. Одна из техник, которая часто используется в моих исследованиях, - это использование обратных вызовов. Хотя я понимаю процесс написания и выполнения функции обратного вызова, я запутался, почему обратные вызовы автоматически делают выполнение JavaScript асинхронным. Итак, мой вопрос: как добавление функций обратного вызова в мой код JavaScript делает указанный код автоматически асинхронным?

Зак Дзюра
источник
2
Возможно, вас заинтересует чтение того, как браузер достигает этого в одном потоке, написанном Джоном Резигом
Jalayn,
@Jalayn. Спасибо. Ваш комментарий имел значение после прочтения нескольких ответов.
kushalvm

Ответы:

26

Это не так. Просто обратный вызов или передача обратного вызова не означает, что он асинхронный.

Например, .forEachфункция принимает обратный вызов, но является синхронной.

var available = false;
[1,2,3].forEach( function(){
    available = true;
});
//code here runs after the whole .forEach has run,
//so available === true here

Он также setTimeoutпринимает обратный вызов и является асинхронным.

function myFunction( fn ) {
    setTimeout( function() {
        fn(1,2,3);
    }, 0 );
}

var available = false;
myFunction( function() {
    available = true;
});
//available is never true here

Подключение к любому асинхронному событию в Javascript всегда требует обратного вызова, но это не означает, что вызов функций или их передача всегда асинхронны.

Esailija
источник
2
@ SteveEvers Я думаю, вы могли бы редактировать статью MDN тогда. Обратный вызов - это очень распространенный термин в javascript для любой функции, переданной другой, которая вызывает вас обратно с помощью функции, которую вы дали ... зачем это усложнять? Изменить: Обратный
вызов
3
@SteveEvers «обратный вызов подразумевает асинхронность» - идиосинкразия C # / Microsoft. en.wikipedia.org/wiki/Callback_(computer_programming)
Esailija
1
@MikeBrown Я полагаю, я слишком много прочитал в его профиле, и этот ответ с наибольшим количеством голосов, безусловно, дает представление о том, что «обратные вызовы подразумевают асинхронность».
Esailija
1
Но, как говорится, @SteveEvers тоже неправильно. Обратные вызовы не подразумевают асинхронность, просто кто-то другой будет отвечать за «обратный вызов».
Майкл Браун
1
+1, потому что Стив Эверс неправ
slebetman
23

Секрет «магии» в том, что события, которым вы назначаете обратные вызовы, являются асинхронными. Они реализованы «под капотом», чтобы позаботиться о том, что они делают (например, извлекать что-то с удаленного сервера) в фоновом режиме, вне песочницы JS. И затем, как только они закончили свою работу, они дают движку JS сообщение для вызова события. Когда механизм JS завершит работу с тем, что он в данный момент делает, он будет вызывать любые события, находящиеся в очереди (или ждать нового сообщения), а затем ваш обратный вызов «магически» вызывается асинхронно!

( ПРИМЕЧАНИЕ. Это концептуальный обзор темы очень высокого уровня, который не углубляется в детали, потому что разные движки JS будут реализовывать вещи по-разному. Но это общая идея того, как это работает.)

Мейсон Уилер
источник
Какие это события? Пример одного или двух таких событий сделает ваш ответ еще лучше.
Джо Смо