Как экспортировать экземпляр класса, который динамически импортируется с помощью модуля ES6 в NodeJS?

#javascript #node.js #express #ecmascript-6

#javascript #node.js #выразить #ecmascript-6

Вопрос:

Я читаю книгу, представляющую NodeJS с простым примером веб-приложения. Требование в примере заключается в том, что в его собственном модуле имеется несколько классов хранилища данных, и нам нужно динамически адаптировать хранилище данных, задав переменную среды. Фрагменты кода примера выглядят примерно так:

 // memory-store.mjs
// The data store for storing data in memory

export default class MemoryStore {
  // Some CRUD operation
}
 
 // fs-store.mjs
// The data store for storing data into file system

export default class FSStore {
    // Some CRUD operation
}
 
 // store.mjs
// Provide a async function to import data store dynamically and
// set the instance to variable store, which is exported

let store;

async function load() {
    try {
        const moduleName = process.env.MODULE_NAME ?? 'memory';
        const storeModule = await import(`./${moduleName}-store.mjs`);
        const storeClass = storeModule.default;
        store = new storeClass();
        return store;
    } catch(err) {
        throw new Error('Something goes wrong...');
    }
}

export { load, store };
 
 // app.mjs
// Import the function to load the data store dynamically and
// the exported store for fetching data list

import express from 'express';
import { load, store } from './store.mjs';

const app = express();

load()
.then(store => {})
.catch(err => console.error(`Exception with error: ${err}`));

app.use('/', (req, res, next) => {
    const dataList = store.retrieveAll();
    res.send(dataList);
});
 

Приведенные выше фрагменты кода отличаются от приведенных в книге в целом. Но концепция та же. Он отлично работает в моей локальной среде, но мне интересно, нет ли проблем, если запрос поступает и обрабатывается до импорта хранилища данных из-за того, что функция импорта выполняется асинхронно? Существуют ли другие решения, которые могут удовлетворить это требование? Или я просто что-то упускаю, что пример из книги — просто шедевр? Заранее спасибо!

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

1. Предоставленный вами код (который » отличается от приведенного в книге «) имеет недостатки. Вы не указали пути эвакуации в случае load() сбоя функции. Ваш сервер продолжит работать и завершится сбоем. Не могу судить о том, что » книга — просто шедевр «, поскольку вы перефразировали.

2. Как это было сделано в книге? Мы не сможем помочь вам в сравнении, если вы не предоставите оба способа. Черт возьми, вы даже не указали, какую книгу вы читаете!

3. Просто используйте await верхнего уровня, он был создан для подобных вещей.

4. Ваш код не работает, если перед инициализацией есть запрос store .

Ответ №1:

Если вы хотите гарантировать, что store он был инициализирован до обработки любых запросов вашим приложением express, вы можете настроить экспресс listener после выполнения load обещания. Это было бы так же просто, как следующее:

 import express from 'express';
import { load, store } from './store.mjs';

const app = express();

app.use('/', (req, res, next) => {
    const dataList = store.retrieveAll();
    res.send(dataList);
});

load()
.then(() => {
   app.listen(port, () => {
     console.log(`Example app listening at http://localhost:${port}`);
   });
})
.catch(err => console.error(`Exception with error: ${err}`));