асинхронный конструктор в nodejs - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь запустить 'Mongoose' и продолжить свою задачу, только когда она подключена, но происходит следующее: сначала запускается задача, а затем подключается Mongo

export class App {
    constructor() {
        console.log("a1");
        this.config();
        console.log("a2");
    }
    public async config() {
        // Connect to MongoDB
        console.log("b1");
        try {
            await mongoose.connect(stringConnection, { useNewUrlParser: true }).finally();

            console.log("MongoDB Running");
        } catch (error) {
            console.log(error);
            process.exit();
        }
        console.log("b2");
    }
}

Ответ:

a1
b1
a2


MongoDB Running
b2

Ответ, который я хотел:

a1
b1


MongoDB Running
b2
a2

Ответы [ 3 ]

2 голосов
/ 04 апреля 2019

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

Правильный способ справиться с этим - иметь асинхронные хуки, которые выполняются вне класса:

export class App {
    constructor() {}

    async init() {
        console.log("a1");
        await this.config();
        console.log("a2");
    }

    async config() {
       ...
    }
}

...

const app = new App();
await app.init();
0 голосов
/ 04 апреля 2019

Хороший способ - узнать о Обещаниях

Хорошим способом может быть возвращение в конфигурации Promise, после чего вы можете использовать функцию then в Promise.

0 голосов
/ 04 апреля 2019

Вы можете использовать Promise.then (потому что async функция бездействия возвращает Promise s), набивать вещи, которые вы хотите сделать после вашего config(), в своем then обратном вызове.

constructor() {
  console.log("a1");
  this.config().then(_ =>
    console.log("a2");
  });
}
...