检测async.queue完成的时间

时间:2018-09-28 19:04:14

标签: node.js asynchronous dns queue

我要在async.queue(https://github.com/caolan/async)中添加很多域名,然后进行dns查找。由于某种原因,异步库中的排水事件被调用的太早了,无论是在队列开始时还是在调用之后。我想知道队列何时真正结束,以便可以使用结果。

如果有人可以推荐其他库或方法来排队作业,而我不需要使用此异步库,我只是想使它工作。

const dns = require('dns');
const async = require('async');
const MaxConcurrent = 2; // only do x DNS lookups at one time
const MaxWait = 1000; // wait for a second before dns timeout


var dnsQueue = async.queue(function(domain, lookupAgain) {
setTimeout(
function() {
dns.resolve(domain, function (err, address) 
{
console.log('domain: ' + domain + " address: " + address)
});
lookupAgain();
}, MaxWait);
}, MaxConcurrent);


// This should run when the queue is finished
dnsQueue.drain = function() {
console.log('done??');
}

// Array of domain names
var uniqueDomains = [
'google.com',
'yahoo.com',
'ask.com',
'cnn.com',
'real.com'
];

// Push each domain name into the dnsQueue
uniqueDomains.forEach(function(domain) {
dnsQueue.push(domain);
});

3 个答案:

答案 0 :(得分:4)

如果您使用的是Nodejs v7.6及更高版本,则不妨尝试async / await。 以下是在nodejs应用程序中使用async / await的示例:

async function fun1(req, res){
  let response = await request.get('http://localhost:3000');
    if (response.err) { console.log('error');}
    else { console.log('fetched response');
}

在上面的示例中,代码要求运行代码的javascript引擎等待request.get()函数完成,然后继续执行下一行。 request.get()函数返回一个用户将等待的Promise。在异步/等待之前,如果需要确保函数按期望的顺序运行,即一个接一个地运行,则将它们一个接一个地链接或注册回调。

有关异步/等待的更多信息,请点击以下链接:

答案 1 :(得分:3)

我为您创建了一个异步队列系统:https://github.com/rehat101/queue.js

您无需显式推动或耗尽。您可以运行该作业,它将为您推送和刷新。如果您不在乎作业何时完成,这将很有用。

尝试克隆存储库并执行以下操作:

import Queue from './src/queue';
import Promise from 'bluebird';

const { Resolver } = require('dns').promises;
const resolver = new Resolver();

let domains = [
'google.com',
'yahoo.com',
'ask.com',
'cnn.com',
'real.com'
];

(async function() {
    let queue = new Queue({concurrency: 1});
    domains.forEach(domain => queue.run(async () => {
        await Promise.delay(1000);
        console.log( await resolver.resolve(domain) );
    }));
})().catch(console.error);

您可以添加数千个工作,这将立即创建1000个未解决的承诺,但只会在并发级别解决承诺。

我计划添加更多功能并将其放在npm上。

答案 2 :(得分:2)

这是因为您已将lookupAgain()放在dns.resolve之前。 刚刚更改了lookupAgain()的位置。

const dns = require('dns');
const async = require('async');
const MaxConcurrent = 2; // only do x DNS lookups at one time
const MaxWait = 1000; // wait for a second before dns timeout


var dnsQueue = async.queue(function(domain, lookupAgain) {
  setTimeout(
    function() {
      dns.resolve(domain, function(err, address) {
        console.log('domain: ' + domain + " address: " + address)
        lookupAgain();
      });
    }, MaxWait);
}, MaxConcurrent);


// This should run when the queue is finished
dnsQueue.drain = function() {
  console.log('done??');
}

// Array of domain names
var uniqueDomains = [
  'google.com',
  'yahoo.com',
  'ask.com',
  'cnn.com',
  'real.com',
  'google.com',
  'yahoo.com',
  'ask.com',
  'cnn.com',
  'real.com'
];

// Push each domain name into the dnsQueue
uniqueDomains.forEach(function(domain) {
  dnsQueue.push(domain);
});

我检查了它是否工作正常。