Meteor / Node.js:for循环中的多个http请求,在一个定时间隔内均匀分布?

尊敬的JS开发人员 –

我试图在一个Meteor应用程序中按时间间隔进行一批服务器端http请求,并根据收到的响应更新MongoDB数据库。 每15秒钟一批请求应该开始,并且请求的集合应该在15秒内均匀分布(而不是一次性地泛滥API服务器)。 为了均匀地传播请求,我试图使用setTimeout方法。

有两个参数在每个http请求之间改变,这些不同的值存储在两个单独的数组中。 而不是拼出每个http请求(如果您计算两个数组之间的所有组合,20 * 4 = 80),我已经在for循环中编写了一个for循环来大大整合代码。 对于每个响应,如果返回OK,则两个switch语句通过评估它的iy值来处理响应的处理方式。

问题:我似乎在“回拨地狱”。 当响应从服务器到达时, i和/或y的值有时已经被循环系统增加了,所以我不能100%确定地用switch语句处理响应。 updatedb()函数最终对错误响应执行特定的计算(将它们存储在数据库中的错误位置)。

希望有人可以提供一些指导,我可以做不同的事情来解决这个问题,因为我在智慧的结尾。

PS我试图用recursion的方法做到这一点,但得到了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); 

 for (i=0;i<array1.length;i++) 

这是Javascript中的致命错误之一。 你声明了一个全局variablesi并迭代该全局variables。 这样迭代的每一个循环都会迭代SAMEvariables。 不是你想要的我相信。

经验法则: 总是用var关键字声明variables。

(例外:有意创build全局variables。)

 for (var i=0; i<array1.length; ++i) 

你的代码的第二个问题比较棘手,但幸运的是众所周知的。 看看这个代码:

 var funs = []; for(var y=0; y<10; ++y) { var print = function() { console.log(y); } funs.push(print); } for(var i=0; i<funs.length; ++i) { funs[i](); } 

当你运行代码时,你期望什么打印到控制台? 想想看。 然后检查出来: http : //repl.it/Uzb 。

您在该页面看到的第二个警告说明了这一点: 不要在循环中创build函数 。 会发生什么情况是,在函数体内部使用的variablesy是指在for块之外的variablesy作用域,在你定义的每个函数被调用的时候已经增加到了10 。 所以console.log(y)总是parsing为console.log(10)

经验法则: 不要在循环中做function。

您可以在调用后更新的元素上使用事件。

举个例子,你可以看看http://test-this.ro/assign-the-same-tests-to-the-zephyr-suites-after-they-are-moved-to-other-project/ line#19 “$('body')。on('requestscompleted',function(){…”