node.js - 根据 API 请求失去与 SQL Server 和 Node 的连接

标签 node.js sql-server api axios es6-promise

我试图循环查询以获取给定大小的结果,在进行第一个查询后,它给了我一个错误

我尝试重新打开连接,它告诉我它已经打开,当我尝试仅使用第一个连接时,它说它已关闭

axios.defaults.headers.common['X-API-KEY'] = apiKey;
axios.defaults.headers.common['Content-Type'] =  'application/json';
axios.defaults.baseURL = 'https://v2.namsor.com/NamSorAPIv2';

const selectStatment = "SELECT [CandidateId] AS id, ( CASE LEN(REPLACE([CandidateName],' ','')) WHEN LEN([CandidateName]) - 1 then PARSENAME(REPLACE([CandidateName],' ','.'), 2) ELSE PARSENAME(REPLACE([CandidateName],' ','.'), 3) END ) AS firstName, PARSENAME(REPLACE([CandidateName],' ','.'), 1) AS lastName ";
const cleanWherequery = 'WHERE NOT firstName IS NULL OR NOT firstName IS NULL ANd NOT lastName IS NULL';
const sqlTable = '##apiTable';
const tempQuery = `DROP TABLE IF EXISTS ##apiTable, ##clean; ${selectStatment} INTO ##clean FROM [dbo].[DimCandidate]; SELECT * INTO ${sqlTable} FROM ##clean ${cleanWherequery}`;
const orderByFetch= `ORDER BY lastName DESC OFFSET ${i * 100} FETCH NEXT 100`
const countQuery = `SELECT COUNT(*) AS Count FROM ${sqlTable}`

const conn = new sql.ConnectionPool(dbConfig);

conn.connect()
.then(function(){
  const reqCount = new sql.Request(conn);

  reqCount.query(`${countQuery}`)
  .then(function(recordset){
    let opt = recordset.recordset[0]['Count'];
    let segCount = Math.ceil(opt/100);
    console.log(segCount);
    return segCount;
    sql.close()
  })
  .then(function(count){
    conn.connect()
    .then(function(){
      const req = new sql.Request(conn);
      for(let i = 0; i < count; i++){
        req.query(`SELECT TOP 201 id, firstName, lastName FROM ${sqlTable} ${orderByFetch}`)
        .then(function (recordset) {
          for(i = 0; i < count; i++){
            console.info(recordset.recordset);
            const jsonSet = {
              'personalNames': recordset.recordset
            }
            console.log(jsonSet);
            getRace(jsonSet);
            getGender(jsonSet)
          }
        }).catch(e =>{
          console.log(e);
        })
      }
  })
}).catch(function (err) {
    console.log(err);
    conn.close();
  })
})
.then(function(){
  conn.close();
})
.catch(err => {
  console.log(err);
  conn.close()
})
.catch(function(e){
  console.log(e);
})

预期的结果是循环查询并发出 api 请求,当前的问题是发出第二个查询

最佳答案

我已经进一步调查并找到了这个问题的答案 - 正如我怀疑的那样,这是由于使用 Promise 嵌套单独的异步序列所致。

出现问题的原因是代码创建了两个异步路径,一个位于另一个内部。您可能会认为外部异步路径等待内部异步路径完成,但事实并非如此 - 内部路径在外部路径内启动,但一旦启动,就会单独执行,而外部执行路径则异步继续。

当使用带有 .then(...); 步骤的 Promise 时,请务必记住,处理 Promise 解析的函数现在位于单独的执行路径上,并且 then(...); 子句后面的代码在 Promise 解析之前执行。

为了说明这一点,我创建了一个测试函数,它阐明了 OP 代码中的情况。该代码的目标是执行五个步骤:

  1. 打开数据库连接
  2. 将数据加载到临时表
  3. 从临时表中读取数据
  4. 报告数据
  5. 关闭数据库连接

出现问题的原因是,由于 .then(..) promise 的嵌套,第 5 步甚至在第 2 步完成之前就已执行:

function TestLostConnection(){
    console.log( ">> START TestLostConnection")
    const loadTempTable = "IF OBJECT_ID('tempdb..##tempTable') IS NOT NULL DROP TABLE ##tempTable; SELECT TOP(1) * INTO ##tempTable from Sys_TestData; ";
    const readTempTable = "SELECT * FROM ##tempTable;"

    // Get connection pool from DB API
    const conn = darwinDB.newConnectionPool();

    // Open the connnection, then access the database
    console.log( "  ### STEP 1: Initiating async database access" );
    conn.connect().then( 
        function(){ 
            console.log( ">> START ASYNC SEGMENT #1" );

            // Get a new request from the connection pool
            let req = new sql.Request(conn);

            // Use request to load the temp table
            console.log( "  ### STEP 2: Running query to load temp table" );
            req.query( loadTempTable ).then(
                function(){

                    console.log( ">> START ASYNC SEGMENT #2 - temp table has been loaded" );

                    // Get new reqeuest from connection pool
                    console.log( "Getting new Request from connection pool");
                    let reqCount = new sql.Request(conn);

                    console.log( "  ## STEP 3: running query to read data from ##tempTable");
                    reqCount.query(readTempTable).then(

                        function(recordset){
                            console.log( ">> START ASYNC SEGMENT #3 - Read from ##tempTable complete" );

                            // Report the data loaded from ##tempTable
                            console.log( "  ## STEP 4: Reporting data to the console")
                            console.dir( recordset );

                            console.log( "<< END ASYNC SEGMENT #3");
                        }
                    )
                    .catch(function (err) {

                        console.log("#### CATCH A")
                        console.log(err);
                        conn.close();
                    })

                    console.log( "<< END ASYNC SEGMENT #2 " )
                }
            ).catch(err => {
                    console.log("#### CATCH B")
                    console.log(err);
                    conn.close()
                }
            )

            console.log("<< END ASYNC SEGMENT #1")
        }
    ).then(function(){
            console.log( ">> START ASYNC SEGMENT #4")
            console.log( "  ## STEP 5: CLOSING CONNECTION" );
            conn.close();
            console.log( "<< END ASYNC SEGMENT #4")
        }
    ).catch(err => {
            console.log("#### CATCH C")
            console.log(err);
            conn.close()
        }
    )

    console.log( "<< END TestLostConnection")

}

这是执行代码时控制台的输出:

>> START TestLostConnection
   ### STEP 1: Initiating async database access
<< END TestLostConnection
>> START ASYNC SEGMENT #1
  ### STEP 2: Running query to load temp table
<< END ASYNC SEGMENT #1
>> START ASYNC SEGMENT #4
  ## STEP 5: CLOSING CONNECTION
<< END ASYNC SEGMENT #4
#### CATCH B
{ ConnectionError: Connection not yet open.

关于node.js - 根据 API 请求失去与 SQL Server 和 Node 的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57596039/

相关文章:

ios - 如何从带有 JSON 数据的字符串中获取 UIImage

javascript - res.sendFile 不是函数 Node.js

node.js - 你如何更新 Mongoose 中的引用文档?

node.js - 切换到输入nodejs的路径

c# - 为什么我需要使用 Npgsql for C# 和 PostgreSQL 引用列和表?

javascript - 未捕获的语法错误 : Unexpected identifier on AJAX call back function

wordpress - wp rest api 每页每个类别帖子

node.js - socket.connect 上的 NodeJS errno 37

sql - SQL Server 中数字范围的通配符

sql - 返回一组列中最高值的最佳实践?