2016-11-22 2 views
0

Я искал и нашел некоторые варианты этого, но не нашел ничего, что точно соответствует моим потребностям. Ниже псевдокод, что я пытаюсь выяснить:Что такое хороший шаблон для ожидания до тех пор, пока количество обещаний не будет завершено, чтобы создать новое обещание?

var itemsUploading = 0; 
const maxUploads = 10; 


function uploadAll(items){ 
    var promises = []; 
    items.forEach(function(item){ 

     /* Here is where I want to wait for itemsCurrentlyUploading < maxUploads */ 

     itemsUploading++;    
     promises.push(upload(item));    
    } 
    return Promise.all(promises); 

} 

function upload(item){ 
    return new Promise(function(resolve, reject){ 

     /*Item upload logic here */ 

    }) 
    .then(function(response){ 
     itemsUploading--; 
    }); 
} 

Я понимаю, что вы не можете блокировать синхронный код ждать асинхронного и я попытался несколько вариаций. Я думаю, что setTimeout - это то, что я могу использовать для этого, но я не могу понять нужную логику. Любая помощь будет очень признательна, и если есть что-то еще, я могу ее изменить, чтобы помочь кому-то лучше понять проблему, просто дайте мне знать, спасибо!

+0

Вам нужно прочитать информацию о цепочке обещаний и отложенных звонков, ключевое слово здесь. .then() ' – rorschach

+2

Посмотрите на [это] (http://stackoverflow.com/a/39197252/1048572) или [это ] (http://stackoverflow.com/a/38778887/1048572) – Bergi

ответ

1

Я думаю, что вы можете найти что-то вроде Promise.map из Bluebird библиотеки полезной. Параметр concurrency позволяет установить максимальное количество «ожидающих» обещаний.

Простое решение, но я думаю, что не так, как проверено в битве как Bluebird, доступно как standalone NPM package.

+0

Это прекрасно, именно то, что я искал. – goodOldFashioned

0

Поскольку JavaScript немного редки в структурах данных, нам нужно будет сделать это.

let pending = new Set; 
let maxPendingItems = 5; // could be whatever number 

let wrapPromiseFn = f => (...args) => { 
    let p = f(...args); 
    pending.add(p); 
    p 
    .then(() => pending.remove(p)) 
    .catch(e => { 
     console.warn(e); 
     pending.remove(p); 
    }); 

    return p; 
}; 

let performAsyncIO = wrapPromiseFn(someAJAXFn); 

Теперь вы можете иметь цикл, который контролирует размер набора, чтобы увидеть, если он очистил достаточно, чтобы добавить новые элементы. Просто убедитесь, что вы украшаете свои функции Promise с возвратом wrapPromiseFn, как указано выше.

let flag = true; 
while (flag) { 
    if (pending.size <= maxPendingItems) { 
    // promise will automatically queue until resolved 
    performAsyncIO().then(responseHandler); 
    } 
} 

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

  • Нет связанных вопросов^_^