#javascript #node.js #async-await
#javascript #node.js #async-ожидание
Вопрос:
Я новичок в node js и пытаюсь понять, как работает асинхронный код. В приведенном ниже примере будет nonAsyncMethod
возникать условие гонки при проверке, содержит ли массив элемент или это nonAsyncMethod
блокировка?
async function example(inputs) {
const array = [];
await Promise.all(inputs.map(async (input) => {
syncMethod(input, array);
}));
}
function nonAsyncMethod(input, array) {
if (!array.includes(input)) {
array.push(input);
}
}
Комментарии:
1. Метод map не завершится, пока
syncMethod
не завершится.
Ответ №1:
.map()
и nonAsyncMethod()
полностью синхронны. Поскольку Javascript запускает ваш основной поток Javascript как единый поток, все здесь будет последовательным (по одному за раз), и нет условий гонки или возможностей для условий гонки.
Также нет причин использовать Promise.all()
здесь вообще синхронный код. Это не дает никаких преимуществ и просто излишне усложняет код. Вы ничего не возвращаете из .map()
обратного вызова, поэтому вы будете вызывать Promise.all()
массив undefined
значений, поэтому он не сделает ничего полезного.
Здесь произойдет то, что вызовет интерпретатор inputs.map()
. Это позволит найти первый элемент в inputs
, а затем вызвать обратный вызов, который вы передали .map()
. Когда этот обратный вызов вернется, его возвращаемое значение будет добавлено к результирующему массиву и тогда, и только тогда .map()
перейдет к следующему элементу в массиве и вызовет следующий обратный вызов. Поскольку ваш обратный вызов полностью синхронен, все просто выполняется в ожидаемой последовательности без возможности возникновения условий гонки.
Тот факт, что вы завернули свой .map()
в Promise.all()
, вообще не меняет .map()
поведение. Также имейте в виду, что .map()
выполняется перед Promise.all()
выполнением.
будет ли у nonAsyncMethod условие гонки при проверке, содержит ли массив элемент, или nonAsyncMethod блокируется?
Нет.
Комментарии:
1. полностью синхронный ? Есть ли у вас какая-нибудь шкала в процентах от синхронности ? Интересно, как будет выглядеть 10% -ная синхронная функция 😉
2. @marzelin — Все, что я имею в виду, это то, что все там синхронно.
3. Я знаю, но если бы в коде была одна асинхронная строка, была бы эта функция синхронной на 99%? Или это было бы асинхронно, а?
4. @marzelin — Во-первых, объявление функции
async
ничего не делает асинхронным. Но включение ЛЮБОЙ асинхронной операции внутри блока кода делает по крайней мере часть операции асинхронной (не полностью синхронной). Проценты здесь не имеют смысла. Вы либо полностью синхронны, либо нет.5. это хороший момент.
async
функция не является полностью асинхронной — она синхронна до первогоawait
.
Ответ №2:
Я предполагаю, что вы собираетесь вызывать эти функции одну за другой? Тогда в этом случае они должны выполняться просто как код синхронизации. Причина в том, что JavaScript использует только один поток для основного выполнения, и до тех пор, пока что-то откладывает выполнение (например, setTimeout
запрос AJAX), он будет выполнять весь синхронный код, даже внутри async
функций, в обычном порядке.
Ответ №3:
Promise.all
принимает Array
of promises
.
async
требуется только в том случае, если функция, использующая await
внутри него
Здесь : async
допустимо, поскольку мы имеем await
внутри функции.
async function example(inputs) {
const array = [];
await Promise.all([promises]);
}
Добавление non promise
функции nonAsyncMethod
не поможет, потому что это не promise.