#javascript #node.js #ecmascript-6 #es6-modules
Вопрос:
У меня есть класс JS/ES6 с конструктором, который должен динамически загружать зависимость на основе переданных ему настроек.
Он отлично работает с синтаксисом CommonJS:
class Example {
handler = null;
constructor(dependency) {
try {
this.handler = new (require(dependency))();
} catch {
throw new Error(`${dependency} not installed`);
}
}
/* ... */
}
Однако мне не удалось заставить его работать должным образом в формате модуля ES6. Вот и все, до чего я смог добраться:
class Example {
handler = null;
constructor(dependency) {
try {
this.handler = new (await import(dependency)).default();
} catch {
throw new Error(`${dependency} not installed`);
}
}
/* ... */
}
Это не работает , потому что вы не можете использовать await
без async
, и конструктор класса не может быть async
.
Без await
этого дальнейший код , как правило, завершается ошибкой, так как нет гарантии, что зависимость была загружена вовремя.
Я не могу загрузить зависимость вне класса обычным способом, потому что это может быть практически любая произвольная зависимость, определяемая потребителем класса.
Я бы предпочел не иметь отдельного метода инициализации/сборки, о котором потребителю нужно беспокоиться. В идеале вы должны иметь возможность просто выполнять const ex = new Example('some-dependency')
, а затем иметь мгновенный доступ к методам класса в ex
, без какой-либо необходимости в дополнительных шаблонах на стороне потребителя.
Конструктор, конечно, мог бы вызвать метод статической сборки, но это, похоже, просто перемещает асинхронную проблему в другое место.
Существует ли установленный шаблон или взлом kludgey для достижения этой цели в модулях ES6?
Комментарии:
1. если вы не можете использовать асинхронность, используйте Promise
2. Если вы динамически импортируете, то вы выбираете асинхронное поведение. Можете ли вы экспортировать
async function createExample(dependency) { const dep = await import(dependency); return new Example(dep); }
вместо этого? В противном случае ваш единственный вариант состоял бы в том, чтобы все, что используетсяthis.handler
, было асинхронным, и чтобы этот код был тем, что выбрасывается в случае сбоя импорта.