在 Promise.All 中释放 MySQL 连接

Posted

技术标签:

【中文标题】在 Promise.All 中释放 MySQL 连接【英文标题】:Release MySQL connections in a Promise.All 【发布时间】:2020-02-24 00:39:53 【问题描述】:

我想释放 mysql 池提供的连接。 在“for”循环中,连接被正确释放,但如果我使用 Promise.All 异步执行它,我有一些未关闭的连接。 问题是,过了一会儿,我收到错误“连接太多”,我不想增加 max_connection 数。

您知道是否由于某种原因,MySQL 连接无法在异步函数中释放?

这是我创建游泳池的方法:

dbPool = mysql2.createPool(Object.assign(, defaultDBConfig, 
            database: 'my_db,
            waitForConnections: true,
            connectionLimit: 10,
            queueLimit: 0,
            multipleStatements: true,
            dateStrings: true
        ));

这是我使用的功能:

/**
 * @description Allow to do a generic async forEach loop
 * @param * array
 * @param * callback
 */
async function asyncForEachPromised(array, callback) 
    await Promise.all(array.map(async (items) => 
        await callback(items);
    ));
/**
 * @description ExecuteQuery a query and return an object which contain the result or an error
 * @param * dbPool Connection pool
 * @param * query Query to executeQuery
 * @param * errorMessage Error message to send to the front-end
 * @param * elements Array of parameter to send in the query
 */
async function executeQuery(dbPool, query, errorMessage, elements) 

    const status = 
        error: null,
        result: null
    ;

    const  error, connection  = await dbPool.getConnection();

    if (error) 
        console.log(error);
        status.error = 'Error when trying to connect to the database.';
     else 
        try 
            const [rows] = await connection.promise().execute(query, elements);
            connection.release();
            status.result = rows;
         catch (err) 
            console.log(err);
            status.error = errorMessage;
        
    
    return status;

最后,有一个我使用的代码示例,在这种情况下连接没有释放:

const elements = [prop1: 'a',prop1: 'b'];
await asyncForEachPromised(elements, async (element) => 
    await executeQuery(dbPool, 'my query', 'my error message', [element.prop1]);
);

但在这种情况下,它们被正确释放:

const elements = [prop1: 'a',prop1: 'b'];
for (const [,element] of elements.entries()) 
    await executeQuery(dbPool, 'my query', 'my error message', [element.prop1]);

【问题讨论】:

能否发布示例代码 sn-p 以便我们更好地为您提供帮助? 【参考方案1】:

你不能那样做。

试试这个

Promise.all( arr )
.then( results => //your code with results)
.finally( () => //close connection)
.catch( e => //do what you need )

但是……你真的应该尝试使用连接池。你用什么 ? mysql节点? https://github.com/mysqljs/mysql#pooling-connections

【讨论】:

以上是关于在 Promise.All 中释放 MySQL 连接的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Nuxt 的 asyncData 中对 Promise.all 进行数组解构

Promise.all()使用方法

理解Promise.all,Promise.all与Promise.race的区别,如何让Promise.all在rejected后依然返回resolved状态

实现promise.all方法

使用 Promise.all() 在 Promise 实现时执行操作

是否可以在 Promise.all 稍后向数组添加一个 Promise?