Выполняются ли обещания, разрешенные во время инициализации модуля, перед сценариями (с ожиданием верхнего уровня?)

#javascript #webpack #browser #es6-modules

Вопрос:

При использовании webpack (v5 через webpacker v6) и экспорте интерфейса (например, через глобальные) в другие сценарии на веб-странице обязательно ли выполняются обещания, разрешенные во время инициализации модуля, до того, как сценарии на странице получат к ним доступ? Есть ли способ гарантировать, что они это сделают? Будет ли ждать работы на высшем уровне?

В частности, представьте, что у меня есть модуль, экспортированный в глобальную библиотеку FOO, который выглядит следующим образом

 ---In module getting webpacked--- class Foo { ... } const done = (async function() {  Foo.bar = 10 - (await prom)/(await other_prom) })() resolve(5); other_resolve(80); //resolve for prom/other_prom await done //if we have top level await export {Foo} --- In (unprocessed) script tag later --- new FOO.Foo(20); //This shouldn't execute until AFTER the async function modifies Foo   

Я бы хотел, чтобы новый FOO.Foo(20) гарантированно не выполнялся до тех пор, пока асинхронная функция выше не завершит выполнение. Есть ли способ гарантировать, что это не будет выполнено до завершения инициализации, кроме как обернуть весь javascript страницы в асинхронную функцию и ожидать всех обещаний инициализации? В этот момент я мог бы просто отказаться от тонкостей асинхронности и написать функции обратного вызова.

Комментарии:

1. Что FOO (все заглавные буквы) в этом коде? Кажется, он появляется из ниоткуда.

2. «… для других сценариев на веб-странице…» Вы буквально имеете в виду сценарии (не-модульный код)?

Ответ №1:

экспорт интерфейса с помощью глобалов в другие сценарии на веб-странице

Нет, не делай этого. Это не является хорошей практикой использовать глобалы, и ожидание высшего уровня не заставит ничего ждать. И не-модульные сценарии все равно не могут использовать ожидание верхнего уровня.

Вместо этого, если вы используете такие модули, как

 export class Foo { ... } Foo.bar = 10 - (await Promise.resolve(5)/(await Promise.resolve(80));  
 import * as FOO from 'the-first-module'; new FOO.Foo(20);  

тогда да, он будет работать так, как ожидалось, и не запустится new Foo до того, как импортированный скрипт завершит свою асинхронную оценку.

Комментарии:

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