Nodejs中async的eachLimit方法内使用superagent的疑惑
Nodejs中async的eachLimit方法内使用superagent的疑惑
在抓网页遇到这样一个问题:
async.eachLimit(dataArr, 100,
function(item, callback) {
superagent
.get('url')
.query({ act: item })
.end(function(err,res){
if (err) {
return console.error("someErr: ", err);
}
var idata = JSON.parse(res.text);
idata = idata.toString() + "\n";
fs.appendFile('data.txt', idata, function (err) {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
});
},
function(err) {
log('Get err: ' + err);
});
每次只获取100个数据后,程序就结束了,没有继续下一批数据获取。不太明白什么原因,希望大侠指点!
标题:Nodejs中async的eachLimit方法内使用superagent的疑惑
内容:
在使用Node.js处理异步任务时,async.eachLimit
方法可以有效地限制同时执行的任务数量,以避免对系统资源造成过大压力。然而,在实际应用中,可能会遇到一些问题,比如你提到的每次只获取100个数据后,程序就停止了,而不是继续下一批数据的获取。
首先,让我们来分析一下你的代码片段:
const async = require('async');
const superagent = require('superagent');
const fs = require('fs');
async.eachLimit(dataArr, 100, // 这里应该是限定的同时处理的最大任务数,例如5
function(item, callback) {
superagent
.get('http://example.com') // 假设这是你要请求的URL
.query({ act: item })
.end(function(err, res){
if (err) {
return callback(err); // 注意这里需要调用callback,将错误传递给eachLimit
}
var idata = JSON.parse(res.text);
idata = idata.toString() + "\n";
fs.appendFile('data.txt', idata, function (err) {
if (err) return callback(err); // 同样,这里也需要调用callback
console.log('The "data to append" was appended to file!');
callback(); // 正常情况下也应调用callback,表示当前任务已完成
});
});
},
function(err) {
if (err) {
log('Get err: ' + err);
} else {
console.log('All data processed successfully.');
}
}
);
解析与修正
-
参数问题:在
async.eachLimit
的第二个参数中,你需要指定的是最大并发任务数,而不是任务总数。例如,如果你想同时处理最多5个任务,应该这样写:async.eachLimit(dataArr, 5, ...
-
回调函数:在每个任务完成时(无论是成功还是失败),都需要调用
callback
函数。这告诉async.eachLimit
当前任务已经结束,可以继续处理下一个任务。在你的代码中,superagent
请求结束后需要调用callback
,并且在文件写入完成后也需要调用callback
。 -
错误处理:确保在出现错误时正确地调用
callback
并传入错误对象,这样async.eachLimit
可以捕获到错误并终止后续任务的执行。
通过上述调整,你的代码应该能够正确地按预期工作,即在限定的最大并发任务数范围内逐个处理数据,并且不会在处理完一部分数据后提前终止。
用async.series https://github.com/caolan/async#seriestasks-callback
没有调用callback函数,在end的时候调用一下callback即可
你提到的问题可能是由于 superagent
请求是异步的,而 async.eachLimit
并没有正确地等待这些异步操作完成。你需要确保每个 superagent
请求完成之后才调用回调函数 callback
。你可以通过使用 async.eachLimit
的错误处理机制来解决这个问题。
示例代码
const async = require('async');
const superagent = require('superagent');
const fs = require('fs');
const dataArr = [/* 你的数据数组 */];
async.eachLimit(dataArr, 100,
function(item, callback) {
superagent
.get('http://example.com') // 替换为实际URL
.query({ act: item })
.end(function(err, res) {
if (err) {
return callback(err); // 使用callback来传递错误
}
try {
const idata = JSON.parse(res.text);
idata = idata.toString() + "\n";
fs.appendFile('data.txt', idata, function (err) {
if (err) {
return callback(err); // 使用callback来传递错误
}
console.log('The "data to append" was appended to file!');
callback(); // 数据写入成功,继续下一个item
});
} catch (e) {
callback(e); // 解析JSON失败,传递错误
}
});
},
function(err) {
if (err) {
return console.error("Some error occurred: ", err);
}
console.log('All data has been processed successfully.');
}
);
关键点解释
- 回调函数:
callback
在superagent
请求完成后被调用,以通知async.eachLimit
下一个数据项可以开始处理了。 - 错误处理:在
superagent
请求或文件写入过程中,如果发生错误,则需要调用callback(err)
来传递错误。这样async.eachLimit
就能知道当前任务已经失败,并停止后续任务。 - 异步操作顺序:确保每个异步操作(如
superagent
请求和文件写入)完成后,才调用callback
,从而允许async.eachLimit
正确管理并发度。
通过这种方式,async.eachLimit
可以正确地等待每个异步任务完成,从而保证所有数据项都被处理。