Странная штука с асинхронными функциями в JavaScript

$ cat x.js
async function print() {
    console.info("abc");
}

print();
$ nodejs x.js
abc

Как это может быть?! print() возвращает неожидаемый объект Promise, не так ли? Если его не ждут, то почему выполняется console.info?

Ну, он должен был напечатать ваш console.info, так как вы его выполнили, а затем вернуть объект Promise, который должен иметь fulfilled в undefined. Как это странно?

choz 23.12.2020 05:38

Отвечает ли это на ваш вопрос? stackoverflow.com/questions/47227550/…

Praveen Kumar Purushothaman 23.12.2020 05:39

@choz Странно то, что abc действительно печатается.

porton 24.12.2020 06:09

@PraveenKumarPurushothaman Это не так.

porton 24.12.2020 06:10
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
4
174
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

да, как сказал Чоз, асинхронные функции возвращают обещание, даже если вы не определили обещание в своем коде.

я думаю, что это возвращенное обещание становится выполненным после того, как все обещания в операторе ожидания будут разрешены.

я тестирую его в следующем коде, он также возвращает обещание, которое выполняется только после того, как все обещания будут разрешены (в этом случае через 3000 мс):

async function print2() {
   await console.info("abc")
    await new Promise((res, rej) => {
        setTimeout(() => {res(33)},3000)
    })
    await new Promise((res, rej) => {
        setTimeout(() => {res(33)},50)
    })
}

«это возвращенное обещание становится выполненным после того, как все обещания в операторе ожидания будут разрешены» - но оператора ожидания нет!

porton 24.12.2020 06:08

извините, мое заявление было неясным, я имею в виду, что в асинхронных функциях возвращенное обещание разрешается после того, как все обещания в функции разрешаются (включая обещания, объявленные с помощью ключевого слова ожидания, вы знаете, что await 3 работает как Promise.of(3)). хотя я не очень четко видно связь между возвращенным обещанием и другими обещаниями в приведенном выше заявлении.

Eason Yu 24.12.2020 07:13
Ответ принят как подходящий

Можно сказать, что сама пустая функция возвращает undefined (что на самом деле ничего не возвращает). Взгляните на образец ниже;

function print() {}
var returnVal = print(); // undefined

Вы заметите, что returnVal это undefined.

Теперь, если у нас есть что-то в body из test(), но вы по-прежнему не передаете никакого возвращаемого значения, то returnVal все равно будет undefined.

function print() {
    console.info('abc');
}
var returnVal = print(); // undefined

Итак, чтобы функция имела возвращаемое значение, ее просто нужно return.

function print() {
    console.info('abc');
    return 1;
}
var returnVal = print(); // 1

Когда вы конвертируете его в асинхронную функцию. Цитата из MDN

  1. Тело асинхронной функции можно рассматривать как разделенное на ноль. или несколько выражений ожидания. Код верхнего уровня, включая первое выражение ожидания (если оно есть) запускается синхронно. В таким образом будет выполняться асинхронная функция без выражения ожидания синхронно. Если внутри функции есть выражение ожидания body, однако асинхронная функция всегда будет выполняться асинхронно.

  2. Код после каждого выражения await можно рассматривать как существующий в .затем обратный вызов. Таким образом, цепочка обещаний постепенно строится с каждым реентерабельным шагом через функцию. Возврат стоимость образует последнее звено в цепи.

Теперь, основываясь на приведенной выше информации, вот что мы знаем о вашем вопросе;

  1. Ваш print() ничего не возвращает, как и должно быть undefined
  2. Асинхронная функция будет выполняться асинхронно, то есть она всегда будет возвращать Promise. Ожидание, выполнение или отклонение

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

async function print() {
    console.info("abc"); // Prints 'abc'
}

// Function above is equivalent to;

function printEquivalentInNonAsync() {
    console.info("abc"); // Prints 'abc'
}

var returnVal = print(); // `returnVal` is `undefined`

И, чтобы ответить на ваш вопрос

Если его не ждут, то почему выполняется console.info?

Независимо от того, ожидается ли асинхронная функция, она все равно выполняется! - Ждет только того, чтобы убедиться, что выполнение строки остановлено до тех пор, пока асинхронная функция (Promise) не будет выполнена или отклонена. Обратите внимание, что первое состояние Promise — ожидание.

Когда выполняется неожидаемая асинхронная функция? Что, если у меня есть f() без await, где f — асинхронная функция в функции синхронизации?

porton 24.12.2020 10:03

Если вы используете await для вызова своей асинхронной функции, она вернет разрешенное значение вместо обещания, которое в вашем случае undefined. Если вы не используете await так, как сейчас, то оно вернется Promise<undefined>

choz 24.12.2020 14:27

Другие вопросы по теме