【发布时间】:2023-03-11 20:07:01
【问题描述】:
亲爱的 JS 开发人员 -
我正在尝试按时间间隔在 Meteor 应用程序中发出一批服务器端 http 请求,并根据收到的响应更新 MongoDB 数据库。每 15 秒,一批请求应该开始,并且这组请求应该在 15 秒内均匀分布(而不是一次性淹没 API 服务器)。为了平均分配请求,我尝试使用 setTimeout 方法。
每个 http 请求之间有两个参数会发生变化,这些变化的值存储在两个单独的数组中。我没有详细说明每个 http 请求(如果计算两个数组之间的所有组合,则为 20*4=80),而是在 for 循环中编写了一个 for 循环,以极大地整合代码。对于每个响应,如果返回正常,则两个 switch 语句通过评估其 i 和 y 值来处理应如何处理响应。
问题:我似乎处于“回调地狱”中。当响应从服务器到达时,i 和/或y 的值有时已经被循环系统递增,所以我不能 100% 确定地使用 switch 语句处理响应。 updatedb() 函数最终会对错误的响应执行某些计算(将它们存储在数据库中的错误位置)。
希望有人能提供一些指导,告诉我我可以采取哪些不同的方法来解决这个问题,因为我已经束手无策了。
附:我尝试使用递归方法执行此操作,但出现Maximum call stack size exceeded 错误。
test = function test(){
// API base URL
var baseURL = "https://example.com/";
// Array1
var array1 = ['item1', // i = 0
'item2', // i = 1
'item3', // i = 2
'item4', // i = 3
'item5', // i = 4
'item6', // i = 5
'item7', // i = 6
'item8', // i = 7
'item9', // i = 8
'item10', // i = 9
'item11', // i = 10
'item12', // i = 11
'item13', // i = 12
'item14', // i = 13
'item15', // i = 14
'item16', // i = 15
'item17', // i = 16
'item18', // i = 17
'item19', // i = 18
'item20']; // i = 19
// Array2
var array2 = ['/path1/', // y=0
'/path2/', // y=1
'/path3/', // y=2
'/path4/']; // y=3
var count = 1;
var timeout = Math.round(interval/(array1.length*array2.length)*count);
// Iterate over each item in array1
Meteor.setTimeout(function() {
for (i=0;i<array1.length;i++) {
// Iterate over each path in array2
for (y=0;y<array2.length;y++) {
var request = Meteor.http.call("GET", baseURL + array1[i] + array2[y]);
// If response is OK, then:
if (request.statusCode == 200) {
// do meaningful things
function updatedb(value) {
switch (y) {
case 0: /*do something with uniqueValue for case of y=0 */; break;
// case 1, case 2, case 3
}
}
switch(i) {
case 0: updatedb(uniqueValue); break;
// case 1, case 2, case 3, case 4, case 5...
}
} else {
throw new Meteor.Error(500, "API call failed with error: " + request.status_txt);
}
}
}
}, timeout);
count++;
}
var interval = 15000;
Meteor.setInterval(function(){
test();
}, interval);
【问题讨论】:
-
迭代器
i和y的作用域仅限于它们所在的函数,而不是 for 循环。按照说明here
标签: javascript node.js asynchronous callback meteor