Определить, когда async.queue закончен - PullRequest
0 голосов
/ 28 сентября 2018

Я добавляю много доменных имен в 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 голосов
/ 04 октября 2018

Если вы работаете с nodejs v7.6 и выше, вы можете попробовать async / await.Ниже приведен пример использования async / await в приложении nodejs:

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() возвращает Обещание, которого ожидает пользователь.Перед асинхронизацией / ожиданием, если необходимо убедиться, что функции выполняются в нужной последовательности, то есть одна за другой, объедините их в цепочку один за другим или зарегистрируйте обратные вызовы.

Для получения дополнительной информации об асинхронности/ Ждите следующих ссылок:

0 голосов
/ 06 октября 2018

Я создал асинхронную систему очередей для вас: 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.

0 голосов
/ 01 октября 2018

Это из-за того, что вы поставили 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);
});

Я проверил, что все работает нормально.

...