Скажем, у меня есть функция, которая выполняет стандартный запрос AJAX:
function doXHR() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts');
xhr.send();
xhr.onreadystatechange = () => {
console.log('ready state change');
};
}
doXHR();
console.log('done');
Этот код заставит браузер запустить запрос AJAX, но в какой момент функция действительно запускает запрос? Согласно этому сообщению: https://blog.raananweber.com/2015/06/17/no-there-are-no-race-conditions-in-javascript/
[Вызов
xhr.onreadystate()
послеsend()
] возможен, потому что запрос HTTP выполняется только после завершения текущей задачи. Это позволяет программисту устанавливать обратные вызовы в любой позиции, которую он пожелает. Поскольку JavaScript является однопоточным, запрос может быть отправлен только тогда, когда один единственный поток может запускать новые задачи. HTTP-запрос добавляется в список задач, которые должны выполняться, которые управляются движком.
Но когда я добавляю точку останова в devtools сразу после отправки вызова:
Я получаю сетевой запрос, хотя в ожидающем состоянии:
В точке останова XHR readystate
равно 1, что равно XMLHttpRequest.OPENED
. Согласно документации MDN, XMLHttpRequest.OPENED
означает, что был вызван xhr.open()
: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
Но если я прокомментирую xhr.send()
так, что вызывается только .open()
:
Тогда я не получаю ожидающий запрос по сети:
Думая, что, возможно, мне нужна область функций для завершения, чтобы запрос действительно был отправлен, я переместил точку останова после вызова функции (и немного изменил код, чтобы увидеть XHR readyState):
Но я все еще получаю ожидающий сетевой запрос:
Похоже, что отладчик не только замораживает выполнение кода, но и любые сетевые запросы. Это имеет смысл, так как вы не хотите, чтобы сетевые запросы завершались, когда вы находитесь на точке останова, но это также не позволяет определить, когда инициируется сетевой запрос.
Мой вопрос: в какой момент запрос действительно отправляется? Позволяет ли вызов xhr.send()
просто настроить запрос, но требует, чтобы область действия объекта заканчивалась до начала запроса? Выполняет ли xhr.send()
запрос перед тем, как заканчивается область действия функции? Или здесь что-то еще происходит?