我试图循环查询以获取给定大小的结果,在进行第一个查询后,它给了我一个错误
我尝试重新打开连接,它告诉我它已经打开,当我尝试仅使用第一个连接时,它说它已关闭
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 代码中的情况。该代码的目标是执行五个步骤:
- 打开数据库连接
- 将数据加载到临时表
- 从临时表中读取数据
- 报告数据
- 关闭数据库连接
出现问题的原因是,由于 .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/