0

我有一个使用 Azure 移动服务作为后端的移动应用程序。我有一个场景,我需要修改客户端从数据库请求的元素。我需要根据其最佳分数和表中所有其他记录的最佳分数来计算所请求记录的排名和百分位数。我按照此处的示例编写了以下脚本:

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();
        }
    });
}

但我没有看到客户端预期的结果。我什至尝试在服务器端记录结果,但我在客户端看到的与记录的不匹配。我究竟做错了什么?

4

1 回答 1

2

这里的问题是该mssql.query函数是异步的。最终发生的事情是,在forEach循环中,您正在触发许多异步 mssql 请求,然后(不等待它们完成)您正在调用 ngrequest.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);
        }
    });
}
于 2013-01-26T23:33:55.383 回答