Почему асинхронные функции не являются асинхронными в node.js? - PullRequest
0 голосов
/ 17 апреля 2019

Этот вопрос может показаться странным, но, насколько я понимаю, асинхронный код должен выполняться независимо от основного потока.Посмотрите на этот код:

async function async() {
    while (true) {

    }
}

async()
console.log('test')

Хотя цикл не блокировал бы этот код, если бы вся функция была асинхронной, а «test» должен быть зарегистрирован на консоли, но этого не происходит.Почему именно так?

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

В Javascript асинхронные функции являются только асинхронными, весь код по-прежнему выполняется в одном потоке.(Исключением является случай, когда вы используете что-то вроде потоков в узле или веб-работников в браузере , для получения дополнительной информации см. Ссылки.)

Дляпроиллюстрируем, что это значит, давайте определим две примерные функции:

function halts() {
  const start = Date.now()
  while (Date.now() < start + 2000);
}

function resolves() {
  return new Promise((resolve) => setTimeout(resolve, 2000));
}

Первая функция будет блокировать поток на примерно 2 секунды, ничего не возвращая, вторая функция вернет Обещание , которое разрешится через аналогичный период времени.

Когда вы используете эти функции, принципиальное отличие состоит в том, что при вызове первой все выполнение блокируется до завершения функции, поскольку всеработает в одном потоке:

function halts() {
  const start = Date.now()
  while (Date.now() < start + 2000);
}

const before = Date.now();
halts();
const after = Date.now();
console.log(`execution halted for ${after - before}ms`);

Разница при использовании асинхронных операций (независимо от того, используете ли вы обещания или async-await для реализации) в том, чтовы можете разрешить основному потоку выполнять другую работу, пока, например, вы не дождетесь завершения сетевого запроса.

function resolves() {
  return new Promise((resolve) => setTimeout(resolve, 2000));
}

const interval = setInterval(() => {
  console.log('ping');
}, 500);

const before = Date.now();

resolves().then(() => {
  clearInterval(interval);
  console.log('promise resolved');
});

const after = Date.now();
console.log(`execution halted for ${after - before}ms`);

Обратите внимание, как во втором примере выполняется немедленное выполнение остальной части кода, а не остановка всего.Асинхронная операция не выполняется в отдельном потоке, ее просто откладывают на более поздний срок в том же потоке.

Для более технического объяснения Ответ Deceze - хорошее краткое резюме, это видео Джейка Арчибальда также является хорошим общим обзором.

1 голос
/ 17 апреля 2019

Асинхронный не означает, что код выполняется в другом потоке . Асинхронное выполнение - это совместная многозадачность в одном потоке . Функции возвращают выполнение обратно в цикл обработки событий через await или путем завершения их выполнения, и цикл обработки событий продолжает свои обратные вызовы выполнения / выполнения при определенных событиях (например, завершение сетевого запроса или завершение таймера setTimeout). Для одной функции все еще вполне возможно захватить поток, используя бесконечный цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...