В вашем примере global.counter
никогда не может заканчиваться сочетанием 'A'
и 'B'
, потому что каждый обратный вызов функции будет выполняться после того, как предыдущий уже завершился. Запросы будут обрабатываться асинхронно , но не параллельно , поскольку для пользовательского кода выполняется только один поток.
Однако, когда у вас есть асинхронные операции внутри функции обратного вызова, например, выборка по сети, доступ к базе данныхили чтение файла, второй пользовательский запрос может завершиться раньше первого и, таким образом, изменить глобальное состояние до того, как первая функция получит к нему доступ.
let state;
function timeout(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
async function req1() {
state = 'A';
await timeout(100);
state += 'A';
console.log(`Req 1: ${state}`);
}
async function req2() {
state = 'B';
await timeout(50);
state += 'B';
console.log(`Req 2: ${state}`);
}
req1();
req2();
// Prints:
// "Req 2: BB"
// "Req 1: BBA"
Это одна из причин, почему это плохая идеяполагаться на глобальное состояние в обратных вызовах запросов HTTP-сервера (например, Express или Koa).