Можно ли использовать await без асинхронности в Js

Await — замечательная функция в es7.

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

Такие как

    async function asy(){
        const [resCityGuess,resCityHot,resCityAll]=await Promise.all([
                        this.http.get('api/v1/cities?type=guess'),
                        this.http.get('api/v1/cities?type=hot'),
                        this.http.get('api/v1/cities?type=group')
        ])
        this.cityGuessName=resCityGuess.data.name;
        this.cityGuessId=resCityGuess.data.id;
        this.cityHot=resCityHot.data;
        this.cityAll=resCityAll.data;
    }
    asy.apply(this);

Я хочу использовать ожидание без асинхронной функции, такой как

        // the async function definition is deleted
        const [resCityGuess,resCityHot,resCityAll]=await Promise.all([
                        this.http.get('api/v1/cities?type=guess'),
                        this.http.get('api/v1/cities?type=hot'),
                        this.http.get('api/v1/cities?type=group')
        ])
        this.cityGuessName=resCityGuess.data.name;
        this.cityGuessId=resCityGuess.data.id;
        this.cityHot=resCityHot.data;
        this.cityAll=resCityAll.data;
        // without call fn

Я думаю, что определение функции fn и вызов этой fn иногда повторяются, поэтому я хочу знать, можно ли оптимизировать ситуацию?

Могу ли я использовать await без асинхронности?

Большое спасибо!


person 曾志强    schedule 07.05.2017    source источник
comment
ответ на ваш вопрос - нет, но если вы используете функцию только один раз, вы можете взглянуть на IIFE (выражение функции с немедленным вызовом)   -  person Gabe Rogan    schedule 07.05.2017
comment
@GabeRogan Я думаю, что это одно из решений. Спасибо.   -  person 曾志强    schedule 07.05.2017
comment
Await — замечательная функция в es7 Это вообще не функция ES 7. Это часть ES 2017.   -  person a better oliver    schedule 08.05.2017
comment
Я действительно хотел бы, чтобы мы могли отрицать комментарии, такие как @JacqueGoupil. Конечно, это имеет смысл: вы можете дождаться результатов промиса, прежде чем продолжить, когда вы не контролируете код, возвращающий промис, или когда он служит двойной цели.   -  person Andrew    schedule 28.08.2019
comment
@Эндрю Этот комментарий был написан до того, как вопрос был сильно отредактирован, и в нем не было упоминания об обещаниях. Читая назад, я признаю, что это был довольно резкий способ сказать, что я не понял вопроса и нуждался в дополнительной информации.   -  person Domino    schedule 28.08.2019


Ответы (3)


Нет. Оператор await имеет смысл только в функции async.

редактировать — для уточнения: вся сделка async и await может рассматриваться как макрос LISP. Что делает этот синтаксис, так это информирует систему интерпретации языка о том, что происходит, чтобы она могла фактически синтезировать преобразование окружающего кода в основанную на Promise последовательность запросов обратного вызова.

Таким образом, использование синтаксиса является неявным коротким путем к кодированию явного материала Promise с вызовами .then() и т. д. Среда выполнения должна знать, что функция является async, потому что тогда она знает, что await выражений внутри функции необходимо преобразовать для возврата Промисы через механизм генератора. И, по пересекающимся причинам, украшение async в объявлении функции говорит языку, что это действительно функция, которая возвращает промис и что с этим нужно справиться.

Итак, это сложно. Процесс улучшения и расширения JavaScript должен учитывать тот факт, что в мире существует невообразимо огромное количество кода JavaScript, и поэтому почти во всех случаях никакая новая функция не может привести к сбою страницы, нетронутой с 2002 года.

person Pointy    schedule 07.05.2017
comment
Спасибо. Я хочу использовать IIFE, чтобы помочь мне. - person 曾志强; 07.05.2017
comment
@曾志强 да, вы можете сделать это: (async function() { ...; await x(); ... })(); - person Pointy; 07.05.2017
comment
Эта документация очень полезна, чтобы понять, почему: developer.mozilla .org/en-US/docs/Web/JavaScript/Reference/ - person craftsman; 09.09.2017
comment
Ответ @Pointy - правильное решение этой проблемы. Точнее (async() => { await x(); })(); - person DARKGuy; 27.04.2018
comment
Используя пример из ссылки Mozilla выше, почему этот код работает без асинхронности, если я вставляю его в консоль? function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); }; await resolveAfter2Seconds(10); - person Jarrod McGuire; 25.05.2018
comment
@JarrodMcGuire, потому что ваша функция возвращает обещание. - person Pointy; 25.05.2018
comment
Но в примере с Mozilla он заключен в дополнительную асинхронную функцию? Нужна ли дополнительная обертка? Кроме того (пожалуйста, простите мою новизну для ожидания/асинхронности), хотя это работает для меня в браузере, это не работает в nodejs - person Jarrod McGuire; 25.05.2018
comment
@JarrodMcGuire хорошо делать что-то в консоли всегда немного странно, потому что все, что предоставляет консоль (браузер или Node), должно создавать какой-то контекст, в котором введенный код может иметь синтаксический смысл. Из-за семантики await его нужно использовать внутри функции async, потому что вызов функции включает в себя обработку возвращаемого промиса и т. д. Это синтаксический сахар вокруг промиса и трюк с поведением функции-генератора. Вызов функции await неявно возвращает из вызывающего контекста то же самое, что и генератор. - person Pointy; 25.05.2018
comment
Спасибо за ваше терпение @Pointy. Только что прочитал кое-что, и я думаю, что упустил то, что вам нужно полностью асинхронизировать (что вы только что подтвердили). await в глобальной области работает, но на практике у вас этого не будет. Я чувствую, что заменил ад промисов/обратных вызовов на асинхронный ад, но я буду настойчив. - person Jarrod McGuire; 25.05.2018
comment
асинхронный ад зашел слишком далеко. Был немного расстроен, потому что я не мог понять это около 2 часов. Думаю, у меня в основном есть это сейчас. Спасибо еще раз - person Jarrod McGuire; 25.05.2018

Это предлагается ECMAScript.

Chrome/Chromium (и все, что имеет современный JS-движок на основе V8) имеет рабочую реализацию, которая соответствует спецификации.

Само предложение находится на стадии 3.

Больше информации:

https://github.com/tc39/proposal-top-level-await

https://v8.dev/features/top-level-await

person Chumpocomon    schedule 17.12.2019

Await верхнего уровня (await без async) пока не является функцией JavaScript.

Однако, начиная с версии 3.8, его можно использовать в Typescript.

Для его использования требуется следующая конфигурация (в tsconfig.json):

"module": "esnext" // or "system"
"target": "es2017" // or higher

Дополнительная информация:

https://typescript.tv/new-features/top-level-await-in-typescript-3-8/

person treecon    schedule 27.07.2021