需要在JavaScript循环迭代中的POST之间延迟

时间:2014-10-09 10:31:28

标签: javascript node.js post get delay

我有一个json文件,我正在迭代它的内容并为每次迭代使用HTTP post请求。 POST请求在数据库中插入信息。我需要在循环中或在POST之间以某种方式引入延迟。我现在拥有的是:

var request = require('request');

for (i = 0; i < arr.length; i++) {
    request.post(
        'http://localhost:3000/post',
        { form: { from: arr[i][0], to: arr[i][1]} },
        function (error, response, body) {
            if (!error && response.statusCode == 200) {
                console.log(body)
            }
        }
    );
}

目前,POST请求几乎是在瞬间被调用,这对于某些需要一段时间的数据库插入逻辑造成了问题。有没有人对如何实施延迟有好主意?

谢谢

4 个答案:

答案 0 :(得分:3)

您遇到的问题是您正在混合同步(循环)和异步(请求)操作。

在继续下一次迭代之前,没有机制让外循环等待内部异步操作完成。

相反,你可以实现递归,要求回调函数启动外部&#34;循环的下一次迭代&#34;。

function do_post_req(arr_key) {
    request.post(
        'http://localhost:3000/post',
        { form: { from: arr[i][0], to: arr[i][1]} },
        function (error, response, body) {
            if (!error && response.statusCode == 200) {
                console.log(body);
                if (arr[key+1]) do_post_req(key+1); //<-- recursion
            }
        }
    );
}
do_post_req(0); //<-- kick things off with first array key

答案 1 :(得分:1)

也许使用setTimeout?虽然看起来很hacky。

var interval = 10;
for (i = 0; i < arr.length; i++) {
    setTimeout(function() {
        request.post(
            'http://localhost:3000/post',
            { form: { from: arr[i][0], to: arr[i][1]} },
            function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    console.log(body)
                }
            }
        );
    }, i * interval);
}

答案 2 :(得分:1)

使用计时器:

var interval = 1000;
function doPosts() {
    if (arr.length == 0)
       return;
    data = arr.pop();
    request.post(
        'http://localhost:3000/post',
        { form: { from: data[0], to: data[1]} },
        function (error, response, body) {
            if (!error && response.statusCode == 200) {
                console.log(body)
            }
        }
    );
    setTimeout(doPosts, interval);
}
doPosts();

答案 3 :(得分:1)

请查看节点https://github.com/caolan/async#eacharr-iterator-callback

的异步模块

添加手动睡眠/等待是一个坏主意,因为回调总是有可能比您设置或失败的手动时间更长。

var request = require('request');
var async = require('async');

async.each(arr, 
  function(arri, cb) {
     request.post(
        'http://localhost:3000/post',
        { form: { from: arri[0], to: arri[1]} },
        function (error, response, body) {
            if (!error && response.statusCode == 200) {
                console.log(body);
                // do you insert stuff here before the cb() call so its done before the next request is executed
                // if the insert stuff is asynchronous as well call cb() inside the callback of your insert
                cb();
            } else {
                cb(error); // only do this if you want to stop at error
            }
        }
    );
  }, 
  function(err) {
    if (err) { console.log(err); }
    else { console.log("all done"); }
  });

如果要并行运行请求,请查看async的并行方法。