Пользовательский метод Promisify

#mysql #node.js #promise #bluebird #node-mysql

#mysql #node.js #обещание #bluebird #узел-mysql

Вопрос:

Я довольно новичок в мире узлов и JS. Чего я пытаюсь достичь, так это «модулировать» мои запросы и повторно использовать их в различных сценариях. Это мой менеджер БД:

 'use strict'

const mysql = require('mysql')
var Promise = require('bluebird')
var using = Promise.using
Promise.promisifyAll(require('mysql/lib/Connection').prototype)
Promise.promisifyAll(require('mysql/lib/Pool').prototype)
const config = require('./config')

var pool = mysql.createPool({
    connectionLimit: 100,
    host: config.dbHost,
    user: config.dbUser,
    password: config.dbPassword,
    database: config.db,
    debug: config.dbDebug
})

var getConnection = function () {
    return pool.getConnectionAsync()
        .disposer(function (connection) {
            return connection.release()
        })
}

var query = function (command) {
    return using(getConnection(), function (connection) {
        return connection.queryAsync(command)
    })
}

module.exports = {
    query: query
}
  

В отдельном файле я хочу вызвать запрос и в зависимости от результата затем вызвать другой (второй использует результирующее значение первого):

 utils.method1()
    .then(function (value) {
        utils.method2(value)
    })
    .catch(function (error) {
        console.error('Error while retrieving product id: '   error)
        res.json({ data: error })
    })
  

Как я могу «обещать» свой метод? Что еще более важно: это правильный способ разделения запросов MySQL? Можете ли вы предложить несколько лучших практик?

Для полноты картины вот мой метод1, который выполняет запрос:

 module.exports = {
    method1: function () {
        // ...sql
        db.query(mysql.format(sql, params))
            .then(function (results) {
                return results[0].id // clearly this is not a promise
            })
            .catch(function (error) {
                console.error('Error while retrieving...: '   error)
                res.status(500).send('Internal server error')
            })
    }
}
  

Ответ №1:

На самом деле вы очень близки к обещанию 🙂

Конечно, results[0].id это не обещание, но это конечное значение единицы.

Что вам нужно сделать, так это вернуть цепочку обещаний вашего запроса :

 return db.query(mysql.format(sql, params))
    .then(function (results) {
        return results[0].id // clearly this is not a promise
    })
    .catch(function (error) {
        console.error('Error while retrieving...: '   error)
        res.status(500).send('Internal server error')
    })
  

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

 method1.then(function(value){
    // Here, value is results[0].id
})
.catch(function(err){
    // Manage a failed query
});
  

Есть отличный пост, который вы, возможно, захотите прочитать о том, как работает Promises: https://blog.domenic.me/youre-missing-the-point-of-promises /

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

1. Просто возврат. =) Большое спасибо. Как бы вы рассмотрели такой скелет кода?

2. Я не уверен, как понять ваш вопрос. Если вы говорите об архитектуре кода, я бы сказал, что это просто. Похоже, вы не используете ORM, подобный Sequelize (возможно, вы захотите взглянуть!). Попробуйте управлять всеми операциями SQL как простым уровнем доступа к данным. Нулевая бизнес-логика. Просто сосредоточьтесь на базовых операциях CRUD и разделите свои объекты на модули узлов. Кроме того, обратите внимание на согласованность, продолжайте возвращать обещания. Если дело было не в этом, ну, извините!