#javascript #asynchronous
Вопрос:
Я хочу, чтобы переменная «остающаяся» была >= 0. Если он достигнет 0, следует прекратить выполнение какой-либо операции вычитания.
Есть 2 асинхронные функции, которые проверят «оставшееся» и выполнят вычитание, если и только если >= 0. Очевидно, что это работает так, как я ожидал, но я действительно понятия не имею, как правильно это решить…
Я прочитал статью https://dev.to/loweisz/how-to-avoid-race-conditions-using-asynchronous-javascript-j30 но я не уверен, что это сработает. Разве та же проблема все еще может возникнуть между «если (!заблокировано) {» и «заблокировано = true;»?
Мне нужна помощь…Ниже приведен мой тестовый код
let remaining = 1000; // remaining should always be >= 0
const fn1 = async () => {
console.log('fn1 invoked');
while(remaining > 0) {
await new Promise(resolve => {
setTimeout(() => {
// This is just a simulation of the delay between "while(remaining > 0) {" and "remaining = remaining - 1;"
resolve();
}, 1);
});
remaining = remaining - 1;
console.log(`fn1 remaining: ${remaining}`);
}
};
const fn2 = async () => {
console.log('fn2 invoked');
while(remaining > 0) {
await new Promise(resolve => {
setTimeout(() => {
// This is just a simulation of the delay between "while(remaining > 0) {" and "remaining = remaining - 1;"
resolve();
}, 1);
});
remaining = remaining - 1;
console.log(`fn2 remaining: ${remaining}`);
}
};
/**
* run async functions
*/
fn1();
fn2();
Комментарии:
1. Да, если у вас есть
await
разница между проверкой (while
условием) и фактической мутацией переменной (remaining = …
), у вас есть условие гонки. Если вы действительно удалите эту искусственную задержку, это сработает — синхронные последовательности операторов выполняются синхронно, без параллелизма.2. Простейший случай, чтобы показать, как это не работает:
for (let i=0; i<2000; i ) fn1();
3. Так что на самом деле искусственная задержка является единственной причиной состояния гонки?
4. В конце концов, в JS нет «одновременного выполнения 2 функций», я правильно понял?
5. Причина в том, что две асинхронные функции / обещания выполняются одновременно