Nodejs async.queue无法控制三个三个执行, 下面代码发现全部执行了.
Nodejs async.queue无法控制三个三个执行, 下面代码发现全部执行了.
//提取邮箱 function pickmail(obj,callback){ var jval = $(obj); //<td> var jurl = jval.parent().attr(‘url’); //<tr> jval.show(); jval.html(’<div class=“pmmsg”></div><strong>邮箱:</strong>’); for(var i=0;i<jsondata.data.length;i++){ if (jsondata.data[i].url==jurl){ downurl(1,[jurl],jval.parent(),jsondata.data[i]); break; } } }
$("#dopickmail").on('click',function(){
//显示邮内容:
var jitems =[];
$(HTML_ID_SEARCHDATA).find('td[colspan="2"]').each(function(index, val) {
jitems.append(val);
});
var q = async.queue(function(obj,pick,callback){
pick(obj,callback);
},3);
/**
* 监听:如果某次push操作后,任务数将达到或超过worker数量时,将调用该函数
*/
q.saturated = function() {
$(HTML_ID_MSGTXT).text('all workers to be used'+q.length());
}
/**
* 监听:当最后一个任务交给worker时,将调用该函数
*/
q.empty = function() {
$(HTML_ID_MSGTXT).text('no more tasks wating');
}
/**
* 监听:当所有任务都执行完以后,将调用该函数
*/
q.drain = function() {
$(HTML_ID_MSGTXT).text('all tasks have been processed');
}
$.each(jitems,function(index,value){
q.push(value,pickmail,function(err){});
});
});
//end 提取
要解决 async.queue
无法控制并发执行的问题,我们需要确保正确地配置队列的并发限制。在你的代码中,你已经设置了队列的最大并发数为3,但可能存在一些细节上的问题。以下是一个调整后的示例代码,并附带一些解释:
示例代码
const async = require('async');
// 提取邮箱
function pickmail(obj, callback) {
var jval = $(obj); // <td>
var jurl = jval.parent().attr('url'); // <tr>
jval.show();
jval.html('<div class="pmmsg"></div><strong>邮箱:</strong>');
for (var i = 0; i < jsondata.data.length; i++) {
if (jsondata.data[i].url == jurl) {
downurl(1, [jurl], jval.parent(), jsondata.data[i]);
break;
}
}
callback(); // 确保每个任务完成后调用回调
}
$("#dopickmail").on('click', function () {
// 显示邮件内容
var jitems = [];
$(HTML_ID_SEARCHDATA).find('td[colspan="2"]').each(function (index, val) {
jitems.push(val); // 使用 push 而不是 append
});
var q = async.queue(function (task, callback) {
pickmail(task, callback);
}, 3); // 设置队列的最大并发数为3
// 监听队列状态
q.saturated = function () {
$(HTML_ID_MSGTXT).text('all workers are being used. Tasks waiting: ' + q.length());
};
q.empty = function () {
$(HTML_ID_MSGTXT).text('no more tasks waiting');
};
q.drain = function () {
$(HTML_ID_MSGTXT).text('all tasks have been processed');
};
// 将任务推入队列
jitems.forEach(function (item) {
q.push(item, pickmail);
});
});
解释
-
pickmail 函数:
- 确保在完成任务后调用
callback()
,这告诉队列该任务已完成。
- 确保在完成任务后调用
-
队列配置:
async.queue(function (task, callback), 3)
设置队列的最大并发数为3。- 在每次调用
pickmail
后,确保调用callback()
,这样队列可以继续处理下一个任务。
-
监听队列状态:
saturated
事件会在队列达到最大并发数时触发。empty
事件会在队列为空时触发。drain
事件会在所有任务都完成时触发。
-
任务推入队列:
- 使用
forEach
方法将任务推入队列,而不是使用$.each
(虽然也可以工作,但forEach
更简洁)。
- 使用
通过这些调整,你应该能够正确地控制 async.queue
的并发执行,使其最多同时执行三个任务。
请大家看哪地方有问题??
根据你的描述,问题可能出在如何正确地使用 async.queue
来控制并发任务的数量。你的目标是每次只处理三个任务。以下是一个简化的示例来展示如何使用 async.queue
来实现这一目标:
const async = require('async');
function pickmail(obj, callback) {
console.log(`正在处理对象: ${obj}`);
setTimeout(() => {
console.log(`完成处理对象: ${obj}`);
callback(null, obj);
}, 1000);
}
// 创建一个队列,限制同时运行的任务数量为3
const q = async.queue(pickmail, 3);
// 模拟需要处理的数据项
const items = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// 设置队列监听器
q.saturated = function() {
console.log('队列已满,当前等待的任务数:', q.length());
};
q.empty = function() {
console.log('没有更多的任务等待处理');
};
q.drain = function() {
console.log('所有任务已完成');
};
// 将任务推送到队列中
items.forEach(item => q.push(item));
console.log('所有任务已推送到队列');
解释:
- pickmail 函数:模拟了处理任务的逻辑。每个任务都有一个超时处理时间(例如1秒)。
- 创建队列:通过
async.queue(pickmail, 3)
创建了一个队列,并指定了最多可以同时运行3个任务。 - 监听器:
saturated
、empty
和drain
是队列的状态监听器,分别用于通知队列已满、无更多任务等待以及所有任务已经完成。 - 推送任务:使用
forEach
遍历需要处理的数据项,并通过q.push(item)
将它们添加到队列中。
以上代码会确保每次最多同时运行三个任务,直到所有任务都被处理完毕。