Ресурсов закрытия в цепочке объектов Promise


Это некоторый код, который извлекает результат из базы данных. Он соединяет, делает запрос, обрабатывает запрос, затем закрыть дБ (при всех возможных ветвей кода) и вернуть результат.

Похоже, что код для закрытия базы данных при любых обстоятельствах-это немного сумбурно. Я интересно, если есть более рациональный способ сделать это?

function getBlocked(data) {
    let openDb;

    close() {
        if (openDb) {
            openDb.close().catch(err => {
                console.log("Error closing db: ", err);
            })
        }
    }

    return MongoClient.connect(url).then(db => {
        openDb = db;
        const blQ = {blocked_user:data.tag_search_mail};
        return db.collection("block_list").find(blQ,{"_id":0}).toArray();
    }).then(results => {
        let blocked = results.map(item => item.blocker);
        close();
        return blocked;     // make this the resolved value of the promise
    }).catch(err => {
        close();
        throw err;          // rethrow to keep the promise rejected
    })
}

Использование:

getBlocked(data).then(blocked => {
    // use blocked array here
}).catch(err => {
    // handle error here
});

К вашему сведению, это сделано намеренно, чтобы вернуть результат, не дожидаясь ДБ закрыть (таким образом, почему это не вставили в цепочке объектов Promise) и регистрировать в журнале только ошибка, не основной операцией при закрытии БД не удается.



Комментарии
1 ответ

Я обнаружил, что node.js В10 поддерживает .finally() для обещания (или вы могли бы использовать полифилл), поэтому он может быть слегка улучшена путем перемещения close() логика в .finally() обработчик.

function getBlocked(data) {
let openDb;

return MongoClient.connect(url).then(db => {
openDb = db;
const blQ = {blocked_user:data.tag_search_mail};
return db.collection("block_list").find(blQ,{"_id":0}).toArray();
}).then(results => {
let blocked = results.map(item => item.blocker);
return blocked; // make this the resolved value of the promise
}).finally(() => {
if (openDb) {
openDb.close().catch(err => {
console.log("Error closing db: ", err);
})
}
});
}


Теперь, кажется, как дополнительное улучшение для данного конкретного использования, вы можете переместить .finally() статья к месту, где вы не должны сохранить db переменной на высоком уровне, потому что все пути с успехом открыть db пройти одно обещание цепи (если нет исключения в .then() обработчик бросается перед db.collection() называется:

function getBlocked(data) {
return MongoClient.connect(url).then(db => {
const blQ = {blocked_user:data.tag_search_mail};
return db.collection("block_list").find(blQ,{"_id":0}).toArray().finally(() => {
db.close().catch(err => {
console.log("Error closing db: ", err);
});
});
}).then(results => {
let blocked = results.map(item => item.blocker);
return blocked; // make this the resolved value of the promise
});
}

0
ответ дан 1 апреля 2018 в 08:04 Источник Поделиться