我有一个移动应用,我正在使用Azure移动服务作为其后端。我有一个场景,在这个场景中,我需要修改客户端从数据库请求的元素。我需要根据记录的最佳分数和表中所有其他记录的最佳分数来计算请求的记录的排名和百分位数。我遵循example here并编写了以下脚本:
function read(query, user, request) {
request.execute({
success: function(results) {
results.forEach(function(item) {
var totalsql = "SELECT COUNT(*) FROM scoreInfo";
mssql.query(totalsql, {
success: function(totalresults) {
var totalCount = totalresults[0].Column0;
var moresql = "SELECT COUNT(*) FROM scoreInfo WHERE bestscore > ?";
mssql.query(moresql, [item.bestscore], {
success: function(moreresults) {
var moreBestCount = moreresults[0].Column0;
item.bestrank = moreBestCount + 1;
item.bestpercentile = 100 - moreBestCount*100/(totalCount+1);
}
});
}
});
});
request.respond();
}
});
}但我在客户端看不到预期的结果。我甚至尝试在服务器端记录结果,但我在客户端看到的结果与记录的结果不匹配。我做错了什么?
发布于 2013-01-27 07:33:55
这里的问题是mssql.query函数是异步的。最终发生的事情是,在forEach循环中,您触发了许多异步的request.respond();请求,在此之后(没有等待它们完成),您调用的是request.respond();,此时您仍然没有任何响应(请记住,node.js是单线程的,所以还没有响应到达)。
您需要做的是延迟调用request.respond(),直到对mssql调用的所有响应都已到达。下面的代码展示了这样做的一种方式。
function read(query, user, request) {
request.execute({
success: function(results) {
var updateResult = function(index) {
if (index >= results.length) {
// all done
request.respond();
} else {
var item = results[index];
var totalsql = "SELECT COUNT(*) FROM scoreInfo";
mssql.query(totalsql, {
success: function(totalresults) {
var totalCount = totalresults[0].Column0;
var moresql = "SELECT COUNT(*) FROM scoreInfo WHERE bestscore > ?";
mssql.query(moresql, [item.bestscore], {
success: function(moreresults) {
var moreBestCount = moreresults[0].Column0;
item.bestrank = moreBestCount + 1;
item.bestpercentile = 100 - moreBestCount*100/(totalCount+1);
updateResult(index + 1); // update next result
}
});
}
});
}
}
updateResult(0);
}
});
}https://stackoverflow.com/questions/14542418
复制相似问题