【发布时间】:2018-01-31 19:47:03
【问题描述】:
我正在我的计算机上开发 NodeJS / ExpressJS 应用程序。我有节点在本地运行。我有一个单页网络应用程序。当它需要信息时,它会使用 jQuery 发出 ajax 请求。
问题是当我对不同的数据集有多个请求时。 Node/express 将开始处理第一个请求,然后在第一个请求完成之前进入第二个请求,它从第一个请求发送对第二个请求的响应,而不是像假设的那样将其发送到第一个请求。如果我在我的应用程序中暂停(使用警报),这样会减慢它的速度,因此在第一个请求完成之前不会发送下一个请求,一切正常。
我不明白为什么会这样。我认为 node / express 应该能够处理这个并将请求分开。
此外,我在节点中收到“发送后无法设置标头”错误,因为它显然正在合并请求....
这就是发生的事情
ajax request 1 -> server
ajax request 2 -> server
ajax request 3 -> server
server -> request1 ( no response )
server -> request2 ( request 1's data)
server -> request3 ( request 2's data)
server for request3 --> error: header's already sent
我在运行 Node 8.9.4 和 Express 4.16.2 的 Windows 10 机器上使用 Google Chrome 63 和 jQuery 3.3.1
我的解决方法是链接 ajax 请求,以便在先前的请求收到来自服务器的响应之前不会调用每个请求。但我不应该这样做......
这里是相关的服务器代码:
var mysql = require("mysql");
var express = require('express');
var app = express();
var DEBUG = true;
var request = null;
var response = null;
var currentDataRowParser = null;
var con = mysql.createConnection(config);
function ParseMySqlRowData(rowData)
{
if (DEBUG) console.log("ParseMySqlRowData");
return JSON.stringify(rowData);
}
var ParseMySqlRowsDatatoResponse = function (err, rows)
{
if (DEBUG) console.log("ParseMySqlRowsDatatoResponse");
var MySQLRows;
try
{
if (!err)
{
MySQLRows = "[";
for (var i = 0; i < rows.length; i++)
{
if (i > 0)
MySQLRows += ", ";
MySQLRows += currentDataRowParser(rows[i]);
}
MySQLRows += "]";
if (DEBUG) console.log("write rows");
if (DEBUG) console.log(MySQLRows);
response.send(MySQLRows);
response.end();
}
}
catch (ex)
{
if (DEBUG) console.log("ParseMySQLRowsDatatoResponse: ERROR");
if (DEBUG) console.log(ex);
}
};
var GetQueryData = function (query, dataRowParser, parseDataCallbackFunction)
{
if (DEBUG) console.log("GetQueryData");
currentDataRowParser = dataRowParser;
if (parseDataCallbackFunction == null || parseDataCallbackFunction == undefined)
parseDataCallbackFunction = ParseDataCallback;
try
{
if (DEBUGQUERY)
{
console.log("before query");
console.log(con.query(query, parseDataCallbackFunction));
console.log("after query");
console.log(query.sql);
DEBUGQUERY = false;
}
else
{
con.query(query, parseDataCallbackFunction);
}
}
catch (ex)
{
console.log(ex);
}
};
app.post('/getdata', function(req, res)
{
request = req;
response = res;
var query;
switch (request.body.loaddata)
{
case "dataset1":
query = "SELECT * FROM table1 WHERE key='" + request.body.key + "'";
GetQueryData(query,ParseMySqlRowData,ParseMySqlRowsDatatoResponse);
break;
case "dataset2":
query = "SELECT * FROM table2 WHERE key='" + request.body.key + "'";
GetQueryData(query,ParseMySqlRowData,ParseMySqlRowsDatatoResponse);
break;
case "dataset3":
query = "SELECT * FROM table3 WHERE key='" + request.body.key + "'";
GetQueryData(query,ParseMySqlRowData,ParseMySqlRowsDatatoResponse);
break;
}
};
【问题讨论】:
-
这实际上是开箱即用的东西,除非你的代码做错了什么。您应该展示您的代码,以便我们帮助调试它。
-
the second request comes in before the first request has been fulfilledJavaScript 是异步执行的。如果您需要更多解释,我们需要查看您的代码 -
我们能看到代码吗?
-
不要将
request和response存储为全局变量。曾经。在调用它们的范围内处理所有内容,而不是全局处理。 -
@PatrickRoberts 解决了这个问题 - 您应该使用来自
app.post处理程序的req和res并在您的回调链与全局变量中使用它。
标签: javascript node.js express