我必须在尽可能短的时间内进行多次API调用。由于我不得不填充各种条件数据集,因此需要进行多次调用。假设我有n
指标,每个指标都会使用m
个可能的过滤器进行过滤。我想得到我生成的n*m
查询的results.totalsForAllResults。
虽然我最初遇到了很多打嗝,knowing about closures解决了许多关于发送异步API调用时出现问题的问题。我甚至能够以正确的顺序处理好结果。现在我遇到一个问题,即每秒API请求的最大数量对我来说是一个问题。 Google Core Reporting API v3每秒最多允许10个API请求,而且我已经超过了此限制。
以下是我尝试进行API调用并处理响应的方法。我对结构没什么自由:
function getMetrics() {
initResultsArray();
for (mI = 0; mI < metricsArray.length; mI++) {
(function (mI) { //Closure. Holds a local value of 'mI' within the scope
for (fI = 0; fI < filtersArray.length; fI++) {
(function (fI) { //Closure. Holds a local value of 'fI' within the scope
gapi.client.analytics.data.ga.get({
'ids': tableID,
'start-date': startDate,
'end-date': endDate,
'metrics': metricsArray[mI],
'filters': filtersArray[fI],
'samplingLevel': 'HIGHER_PRECISION',
}).execute(function putToVar(results) { //this fn is defined inline to get access to fI
console.log(results.totalsForAllResults);
resultsArray[mI][fI] = parseInt(results.totalsForAllResults[metricsArray[mI]]);
});
})(fI); //This ends the closure for fI
}
})(mI); //This ends the closure for mI
}
}
//Print results to console, called when I believe all results have been populated.
function logResults() {
console.log(resultsArray);
}
我需要能够找出我是否在最后一秒内发出了10个查询并等待发送剩余的查询,因为每当我每秒超过10个查询时,我会得到空对象作为我的API调用的响应它破坏了我将值检索到数组中的能力。如何才能做到这一点?我不知道如何使用wait()
,并且有人说如果您使用wait(),浏览器会无响应,我不知道setTimeOut()
如何应用于我的问题。
mI
和fI
是指标和过滤器的全局迭代器,而metricsArray
和filtersArray
是表示GA API预期方式的指标和过滤器的字符串数组,我只需要遍历它们就可以获得很多results.TotalsForAllResults
。执行API调用和响应没有问题。我唯一的问题是超过每秒10个查询限制而没有得到进一步的回复。
答案 0 :(得分:1)
您可以先创建一个需要调用的调用列表,然后再将它们设置为10来解决此问题。这完全不在袖口,所以不能保证它真的有用,但希望你可以将它应用到你的情况。
一般的想法是创建一个简单的Scheduler
构造函数,它接受一系列要处理的东西。更具描述性地命名内容会更好:)。创建的对象只有一个函数 - start
。
var Scheduler = function (stuffToProcess) {
var started,
executeFunction;
getExecuteFunction = function (current) {
return function (results) {
console.log(results.totalsForAllResults);
resultsArray[current.mI][current.fI] = parseInt(results.totalsForAllResults[metricsArray[current.mI]], 10);
};
}
var processNext = function () {
var current = stuffToProcess.shift(),
counter = 0;
while (current && ++counter <= 10) {
gapi.client.analytics.data.ga
.get(current.gaBit)
.execute(getExecuteFunction(current));
if (counter !== 10) {
current = stuffToProcess.shift(); // <- EDIT: Forgot this in original answer.
}
}
if (stuffToProcess.length > 0) {
window.setTimeout(function () {
processNext();
}, 1000);
}
};
this.start = function () {
if (!started) {
started = true;
processNext();
}
};
};
然后在你的getMetrics
函数中,不是直接调用ga,而是构建一个你想要调用的数组,然后创建一个调度程序实例并启动它。
function getMetrics() {
initResultsArray();
var listOfCalls = [];
for (mI = 0; mI < metricsArray.length; mI++) {
for (fI = 0; fI < filtersArray.length; fI++) {
listOfCalls.push({
gaBit: {
'ids': tableID,
'start-date': startDate,
'end-date': endDate,
'metrics': metricsArray[mI],
'filters': filtersArray[fI],
'samplingLevel': 'HIGHER_PRECISION'
},
mI: mI,
fI: fI
});
}
}
var s = new Scheduler(listOfCalls);
s.start();
}
编辑:
修改后的代码改为使用getExecuteFunction
。