неасинхронный метод внутри promise.all

#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.