在then完成准备好的语句执行之前执行finally

问题描述

我是node.js的新手,在连接到mssql数据库并准备/执行准备好的语句时遇到问题。

我有以下代码:

this.connectionPool.connect().then(pool => {
    // Create prepared statement
    stmt = new mssql.PreparedStatement(pool);

    // PREPARE
    stmt.prepare(command,err => {
        //TODO: check for errors in prepare
                
        // EXECUTE
        stmt.execute((err,result) => {
            //TODO: check for errors in execute

            // UNPREPARE
            stmt.unprepare(err => {
                //TODO: check for errors in unprepare
            });

            console.log(`Rows affected: ${stmt.rowsAffected}`);
            console.log(`Result: ${result}`);
            return result;
        });
    });
}).catch(err => {
    console.log(`Connection pool error: ${err}`);
}).finally(() => {
    // Close connection
    console.log("Closing connection.");
    if (this.connectionPool.connected) {
        this.connectionPool.close();
    }
});

我发现finally()诺言与then()同时执行,这是我不期望的。这将导致在准备语句之前关闭连接。

ConnectionError: connection is closed

如何确保仅在语句执行后 关闭连接?

解决方法

回调是异步执行的,因此您需要在承诺链中添加execute的结果:

this.connectionPool.connect().then(pool => {
  // Create prepared statement
  stmt = new mssql.PreparedStatement(pool)

  // return a promise to add it to the promise chain
  return new Promise((resolve,reject) => {
    stmt.prepare(command,err => {
      // TODO: check for errors in prepare
      if (err) {
        reject(err)
        return
      }
      // EXECUTE
      stmt.execute((err,result) => {
        // TODO: check for errors in execute
        if (err) {
          reject(err)
          return
        }

        // UNPREPARE
        stmt.unprepare(err => {
          // TODO: check for errors in unprepare
          if (err) {
            reject(err)
          }
        })

        console.log(`Rows affected: ${stmt.rowsAffected}`)
        console.log(`Result: ${result}`)
        resolve(result)
      })
    })
  })
}).catch(err => {
  console.log(`Connection pool error: ${err}`)
}).finally(() => {
  // Close connection
  console.log('Closing connection.')
  if (this.connectionPool.connected) {
    this.connectionPool.close()
  }
})

如果开箱即用stmt.prepare支持承诺,您可以不将其包装在new Promise中将其返回


所有承诺版本:

this.connectionPool.connect().then(pool => {
  // Create prepared statement
  stmt = new mssql.PreparedStatement(pool)
  return stmt.prepare(command)
    .then(() => stmt.execute())
    .then((result) => {
      console.log(`Rows affected: ${stmt.rowsAffected}`)
      console.log(`Result: ${result}`)
    })
    .finally(() => stmt.unprepare())
}).catch(err => {
  console.log(`Connection pool error: ${err}`)
}).finally(() => {
  // Close connection
  console.log('Closing connection.')
  if (this.connectionPool.connected) {
    this.connectionPool.close()
  }
})
,

.prepare().execute().unprepare()方法都接受回调。除非这些方法被“承诺化”,否则this.connectionPool.connect().then().catch().finally()链无法得知准备-执行-未准备过程的结果。

准备-执行-取消准备过程可以如下进行承诺:

this.connectionPool.connect()
.then(pool => {
    let stmt = new mssql.PreparedStatement(pool);
    return new Promise((resolve,reject) => {
        stmt.prepare(command,err => {
            if(err) {
                reject(err);
            } else {
                stmt.execute((err,result) => {
                    if(err) {
                        reject(err);
                    } else {
                        stmt.unprepare(err => {
                            if(err) {
                                reject(err);
                            } else {
                                resolve(result);
                            }
                        });
                    }
                });
            }
        });
    });
})
.catch(err => {
    console.log(`Prepared statement error: ${err.message}`);
})
.finally(() => {
    if (this.connectionPool.connected) {
        this.connectionPool.close();
    }
});

现在,catch()finally()块将按您期望的顺序排序。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...