我实现的Node.js中类似Sleep的功能,请大家点评!
发布于 10 年前 作者 i2Worker 17847 次预览 最后一次回复是 9 年前 来自 分享
最近在抓取一个网站的数据,它有反爬虫策略,不让我持续访问超过100个网络链接,如果访问一段时间暂停一会的话就可以绕过去了,所以就有了下面这段代码,请大家看看,有没有更好的实现方法,首先说明一下,这个小程序运行在命令行下就可以了,我只要抓取数据就可以了。 实现的思路: 主要是通过setTimeout来实现暂停功能,将要抓取的连接保存在一个数组中,将数组进行分组,每抓取完3个连接就暂停5秒钟,并且结果统一保存在一个外部变量results中。
//测试Nodejs怎样实现Sleep的功能
var async = require('async');
//通过setTimeout函数实现Sleep的功能
var sleep = function(array, callback) {
'use strict';
//初始化变量
var results = []; //存放最终结果
var tmpArray = array.slice(0); //拷贝一份数据,防止改变变量外部的值
var isEnd = false;
//自调用函数
var run = function() {
var tmp = null; //存放截取的数组
if (tmpArray.length > 3) {
tmp = tmpArray.splice(0, 3);
} else {
tmp = tmpArray;
isEnd = true;
}
async.mapLimit(tmp, 2, function(item, itemCallback) {
console.log('Enter: ' + item.name);
setTimeout(function() {
console.log('Handle: ' + item.name);
itemCallback(false, item.name + '!!!');
}, item.delay);
}, function(err, data) {
console.log(data);
results = results.concat(data);
if (isEnd) {
callback(false, results);
} else {
console.log('Sleep 5s');
setTimeout(run, 5000);
}
});
};
run();
};
//测试数据
var arr = [
{name:'Jack', delay:2000},
{name:'Mike', delay: 1000},
{name:'Freewind', delay:3000},
{name:'Test', delay: 2500},
{name:'Woody', delay: 3500},
{name:'Water', delay: 2600},
{name:'Sugar', delay: 1500}
];
sleep(arr, function(error, data) {
'use strict';
console.log(data);
});
9 回复
有 setTimeout 还非要去实现一个 sleep, 很强烈的 Java/C# 即视感.
@TossShinHwa 这个本来就是用的setTimeout功能,只是用它来实现暂停而已。
表示无法理解楼主心态
其实就是递归转迭代??
@qingfeng 好精巧的sleep函数。我在这里学习了。谢谢!!
就是用 settimeout 实现了自己的等待逻辑而已。没什么好点评的
你这样写是递归,可以 setInterval 周期执行run不需要递归;递归的开销大 就是需要将请求的链接资源放在run外面, 和result一个作用域
另外run里面用的 var建议换成let 或者const 否则他们的作用域基本都和result差不多