Вы пытаетесь поддерживать общее состояние для нескольких функций, которые затем выполняются асинхронно.Это очень распространенный случай в JS, и сам язык предоставляет очень простой, но мощный механизм для этого: вы можете обращаться к переменным из внешней функции из внутренней функции, даже если внешняя функция уже завершила свое выполнение:
(function closured() {
let shared = { /*...*/ };
function inner() {
console.log( shared );
}
setTimeout(inner);
})();
Теперь, когда это работает, оно не так хорошо масштабируется для больших приложений: все функции, обращающиеся к этому состоянию, должны быть внутри одной функции, и поэтому этот файл действительно взорван.Библиотеки, которые вы используете, пытаются решить эту проблему, они также используют замыкания для поддержания состояния между асинхронными вызовами: когда вы регистрируете асинхронный обратный вызов, состояние сохраняется в функции, а затем сам обратный вызов помещается в обратный вызов, который восстанавливает состояние:
let state;
function setTimeoutWithState(cb, time) {
const closured = state;
setTimeout(() => {
state = closured;
cb();
}, time);
}
state = 1;
setTimeoutWithState(() => console.log(state), 1000);
state = 2;
setTimeoutWithState(() => console.log(state), 500);
Теперь библиотеке нужно просто обернуть каждый асинхронный обратный вызов таким образом, и тогда вы сможете легко поддерживать состояние, не правда ли?Конечно, это так, но добавление кода к каждому обратному вызову имеет свою стоимость (поскольку JS активно использует обратные вызовы).