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 提取 
3 回复

要解决 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);
    });
});

解释

  1. pickmail 函数:

    • 确保在完成任务后调用 callback(),这告诉队列该任务已完成。
  2. 队列配置:

    • async.queue(function (task, callback), 3) 设置队列的最大并发数为3。
    • 在每次调用 pickmail 后,确保调用 callback(),这样队列可以继续处理下一个任务。
  3. 监听队列状态:

    • saturated 事件会在队列达到最大并发数时触发。
    • empty 事件会在队列为空时触发。
    • drain 事件会在所有任务都完成时触发。
  4. 任务推入队列:

    • 使用 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('所有任务已推送到队列');

解释:

  1. pickmail 函数:模拟了处理任务的逻辑。每个任务都有一个超时处理时间(例如1秒)。
  2. 创建队列:通过 async.queue(pickmail, 3) 创建了一个队列,并指定了最多可以同时运行3个任务。
  3. 监听器saturatedemptydrain 是队列的状态监听器,分别用于通知队列已满、无更多任务等待以及所有任务已经完成。
  4. 推送任务:使用 forEach 遍历需要处理的数据项,并通过 q.push(item) 将它们添加到队列中。

以上代码会确保每次最多同时运行三个任务,直到所有任务都被处理完毕。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!