2014-10-20 4 views
1

У меня есть массив files, что я хотел бы атаковать N за раз. И функция doWork, которая возвращает обещание.Promise based queue

var files = [] 

var doWork = function(file) { 
    return asyncFn(file) 
} 

Я бы хотел,

Редактировать: Я пробовал различные модули (prom-queue, async-q). Все они работают в моде, но они не позволяют использовать массив в качестве очереди. У них есть собственная внутренняя структура, на которую нужно надавить.

Причина, по которой мне нужно использовать массив, поскольку я хочу, чтобы он мог вставить элемент в очередь, и убедитесь, что он еще не находится в очереди.

+2

Пожалуйста, задайте вопрос в своем вопросе. Что вы пробовали и где вы застряли? – jfriend00

+1

Если вы используете Bluebird, у этого встроенного (с массивом) будет ответ, который вас интересует –

+0

Я использую Bluebird, но я не мог видеть метод, который помог мне. Любопытно. –

ответ

0

Вот как вы это сделаете с Bluebird, который вы указали, что используете.

var files = ["foo.txt", "bar.txt", "baz.txt"]; 
var task = Promise.map(files, doWork, {concurrency: 4}); // four at a time 

task.then(function(results){ 
     // results contains the results, tasks are executed at most 4 at a time 
}); 

Слово предостережения - это ставит верхний предел на сколько текущий вызов будет работать, вызывая функцию несколько раз, или из нескольких процессов узлов будет (очевидно) выполняют с большей/меньшей параллелизм. Однако в простом случае - это работает.

+0

Это не похоже на очередь для меня - с '{concurrency: 1}' это может быть. И это не кажется динамическим (я бы предположил, что OP означает, что вы все еще можете добавлять задачи, пока очередь уже запущена)? – Bergi

+1

@Bergi первая строка: «У меня есть массив файлов, которые я бы хотел атаковать N за раз. И функция doWork, которая возвращает обещание». Это не динамический, но это определенно очередь. –

+0

Вы правы - имейте upvote от меня :-). @Dominic: Если вы ищете решение, которое позволяет вам нажимать на очередь, пока оно уже работает, сообщите нам (я сделаю ответ) – Bergi

-1

Вы могли бы сделать что-то вроде этого:

function enq (step) 
    var f = function() { 
    var d = Q.defer(); 
    step(d); 
    return d.promise; 
    } 
    enq_head = enq_head.then(f); 
} 

где шаг является функция, которая выполняет обещание вам передать его. Но я не рекомендую это, потому что это просто причудливый способ сделать то, что setTimeout делает намного эффективнее.

Если вы хотите отслеживать, какие файлы были запланированы и/или завершены, просто поместите их в готовый список или выньте их из списка задач, из которого вы их получите, вставьте bool в объект под имя файла или что-то еще. Это отдельная проблема из планирования.

Смежные вопросы