【发布时间】:2017-11-17 15:53:23
【问题描述】:
我创建了 Node JS 应用程序,我明确地从数据库下载了超过 100000 条记录。当请求正在进行时,我尝试从另一个浏览器登录同一个应用程序,除非前一个请求完成,否则它不会响应。任何想法 ?与事件循环或线程有什么关系? 所以这是我的逻辑。 我在步骤 1 中向我的 API 发出 get 请求,API 在步骤 2 中调用数据库层。数据库仅返回 21 条记录,我明确循环 100000*21 以进行大量渲染,只是为了测试 json2csv 上的负载。这样做时,对服务器的其他请求将不会响应,直到最后一个处理完成。
Step 1:
router.get('/report/downloadOverdueTrainings/:criteria', function (req, res, next) {
var overDueTrainings = [];
var reportManager = new ReportManager();
var result = reportManager.getOverdueTrainings(JSON.parse(req.params.criteria));
result.then(function (result) {
var fields = ['Over Due Trainings'];
for (var i = 0; i < 100000; i++) { //Testing purpose
for (var training of result) {
overDueTrainings.push({
'Over Due Trainings': training.OverDueTrainings
})
}
}
json2csv({
data: overDueTrainings,
fields: fields
}, function (err, csv) {
if (err)
throw err;
res.setHeader('Content-disposition', 'attachment; filename=OverdueTrainings.csv');
res.set('Content-Type', 'text/csv');
res.send(csv);
});
}).catch(function (err) {
next(err);
});
});
Step 2: Database Logic
var xtrDatabaseConnection =require('./xtrDatabaseConnection').XTRDatabaseConnection;
ReportData.prototype.getOverdueTrainings = async function (params) {
var connection = new xtrDatabaseConnection();
var sequelize = connection.getSequelize();
try {
var query = "CALL report_getOverdueTrainings(:p_CourseCode,:p_Revision,:p_RevisionNo,:p_UserGroup,:p_Username,:p_Status,:p_SortColoumnNo,:p_SortColoumnDirection,:p_callType,:p_StartIndex,:p_PageSize)";
var replacements = {
p_CourseCode: params.CourseCode,
p_Revision: params.Revision,
p_RevisionNo: (params.RevisionNo == '' || params.RevisionNo == null) ? 0 : params.RevisionNo,
p_UserGroup: params.UserGroup,
p_Username: params.Username,
p_Status: params.Status,
p_SortColoumnNo: params.SortColoumnNo,
p_SortColoumnDirection: params.SortColoumnDirection,
p_callType: params.callType,
p_StartIndex: params.startIndex,
p_PageSize: params.pageSize
};
//console.log(replacements);
return await connection.executeQuerySequelize(sequelize, query, Sequelize.QueryTypes.RAW, replacements);
} catch (e) {
throw (e);
} finally {
//To close connections
sequelize.connectionManager.close().then(() => console.log('Connection Closed'));
}
}
XTRDatabaseConnection.prototype.executeQuerySequelize = function (sequelize, query, queryType, replacements) {
return sequelize.authenticate()
.then(() => {
return sequelize.query(query, {
replacements: replacements,
type: queryType
}).
then(result => result)
.catch(err => {
throw (err);
});
})
.catch(err => {
xtrUtility.logErrorsToWinstonTransports('Unable to connect to the database or some error occurred while executing your query. ', err);
throw new AppError(err, "dbError", "Unable to connect to the database or some error occurred while executing your query.");
});
}
【问题讨论】:
-
你遇到了什么错误
-
我没有收到任何错误,当我生成下载 csv 文件的请求时,同时执行任何其他功能在文件下载之前它不会响应。这意味着有东西阻塞了。
-
因为for循环阻塞了事件循环,你可以尝试使用集群或子进程
-
你用的是快递吗?
-
完成数据库任务需要多长时间?如果完成,您的登录是否正常?
标签: javascript node.js promise mean-stack es6-promise