В исходном вопросе вы хотите, чтобы они работали параллельно. Вы можете использовать Promise.all для запуска нескольких асин c задач, он будет ждать решения всех асин c задач и вернуть выходной массив.
Promise.all выполняет асин c задачи, выполняя их (последовательно), а не выполняет их технически параллельно, но они работают параллельно. Это даст вам результат, когда все асин c задачи будут решены или отклонены, если какая-либо из них не будет выполнена.
Или вы можете просто запустить их 1 на 1 без Promise.all. они не будут блокировать друг друга, поэтому по-прежнему параллельно, но вы Promise.all просто помогаете вам обрабатывать результаты обратного вызова в одном месте.
Выход будет 12 или 20, в зависимости от случайного времени ожидания, которое вы установили для Функции bar и foo.
Для состояния гонки только функции setTimeout являются асинхронными, но все операции в обратных вызовах являются синхронными и неблокирующими, поэтому поток не будет переходить от операций в одном обратном вызове к другому обратному вызову, если только все операции в этом обратном вызове завершены.
Но в JS при использовании SharedArrayBuffer может сохраняться гонка данных, для которой требуется объект Atomics для предотвращения гонки данных.
let output = 0;
let inputA = 10;
let inputB = 11;
const bar = (cb) => setTimeout(cb, Math.random() * 1000);
const foo = (cb) => setTimeout(cb, Math.random() * 1000);
bar( () => {
inputA++;
inputB = inputA;
output = inputA + 1;
});
foo( () => {
inputB--;
inputA = inputB;
output = inputB * 2;
});
Promise.all([bar(),foo()])
.then(output => console.log('foo and bar tasks finished with output ',output));
setTimeout(() => {
console.log('output variable value: ', output)
}, 2000);