В неблокирующем событии l oop из JavaScript безопасно ли читать, а затем изменять переменную? Что произойдет, если два процесса захотят изменить переменную почти одновременно?
Пример A:
- Процесс 1: Получить переменную A (это 100 )
- Процесс 2: Получить переменную A (это 100)
- Процесс 1: Добавить 1 (это 101)
- Процесс 2: Добавить 1 (это 101)
- Результат: переменная A равна 101 вместо 102
Вот упрощенный пример с маршрутом Express. Допустим, маршрут называется 1000 в секунду:
let counter = 0;
const getCounter = () => {
return counter;
};
const setCounter = (newValue) => {
counter = newValue;
};
app.get('/counter', (req, res) => {
const currentValue = getCounter();
const newValue = currentValue + 1;
setCounter(newValue);
});
Пример B:
Что если мы сделаем что-то более сложное, например Array.findIndex()
, а затем Array.splice()
? Может ли быть так, что найденный индекс устарел, потому что другой событийный процесс уже изменил массив?
- Процесс A findIndex (это 12000)
- Процесс B findIndex (это 34000 )
- Индекс сращивания процесса A 12000
- Индекс сращивания процесса B 34000
- Результат: процесс B удалил неправильный индекс, должен был удалить 33999 вместо
const veryLargeArray = [
// ...
];
app.get('/remove', (req, res) => {
const id = req.query.id;
const i = veryLargeArray.findIndex(val => val.id === id);
veryLargeArray.splice(i, 1);
});
Пример C:
Что если мы добавим операцию asyn c в пример B?
const veryLargeArray = [
// ...
];
app.get('/remove', (req, res) => {
const id = req.query.id;
const i = veryLargeArray.findIndex(val => val.id === id);
someAsyncFunction().then(() => {
veryLargeArray.splice(i, 1);
});
});
Этот вопрос было довольно трудно найти правильные слова, чтобы описать это. Пожалуйста, не стесняйтесь обновлять заголовок.