Правильный способ использования клиента MongoDB в асинхронных / ожидающих экспресс-маршрутизаторах - PullRequest
0 голосов
/ 12 сентября 2018

Как правильно управлять клиентами MongoDB в асинхронных / ожидающих экспресс-маршрутизаторах?

Я пытаюсь создать клиент MongoDB в промежуточном программном обеспечении маршрутизатора, чтобы он был доступен для всех запросов. Вот упрощенный пример:

const express = require('express');
const { MongoClient } = require('mongodb');

let router = express.Router();

router.use(async (req, res, next) => {
    try {
        req.client = await MongoClient.connect(process.env.MONGODB_URI);
        next();
    } catch (err) {
        next(err);
    } finally {
        req.client && req.client.close();
    }
});

router.get('/', async (req, res, next) => {
    let user = await users.findOne({ name: 'foo' });
    if (!user) {
        user = { name: 'foo' };
        await users.insert(user);
    }
    res.json(user);
});

module.exports = router;

К сожалению, после вызова await users.findOne({ name: 'foo' }) выполнение переходит на ветку finally в промежуточном программном обеспечении, соединение MongoDB закрывается, и потенциальный вызов await users.insert(user) из-за этого завершается неудачей.

Спасибо за помощь!

1 Ответ

0 голосов
/ 12 сентября 2018

Откуда вы получаете свою коллекцию пользователей?

И после правильного получения коллекции пользователей вы можете обещать все ваши вызовы БД.

Вы можете использовать Promise.all, чтобы разрешить все сразу

const [user1, user2] = await Promise.all([users.findOne({name: 'user1'}), users.findOne({name: 'user2'})]);

Это разрешит оба обещания одновременно.

Редактировать после обновления кода 1

вы можете использовать {upsert: true}

const user = await users.findOneAndUpdate({name: 'foo'}, {name: 'foo'}, {upsert: true})

И так как ваш следующий () является асинхронным вызовом вашего кодаобязательно перееду, чтобы окончательно заблокировать.

const express = require('express');
const { MongoClient } = require('mongodb');

let router = express.Router();

router.use(async (req, res, next) => {
    try {
        req.client = await MongoClient.connect(process.env.MONGODB_URI);
        next();
    } catch (err) {
        next(err);
    }
});

router.get('/', async (req, res, next) => {
    let user = await users.findOne({ name: 'foo' });
    if (!user) {
        user = { name: 'foo' };
        await users.insert(user);
    }
    res.json(user);

    next();
});

router.use(async (req, res, next) => {
    try {
        req.client && req.client.close();
    } catch (err) {
        next(err);
    }
})

module.exports = router;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...