Promise pool example
by Julien Roche
HTML
<section>
<h1>Concurrency = 3</h1>
<button id="runConccurency3">Run</button>
<ul id="conccurency3"></ul>
</section>
<br />
<section>
<h1>Concurrency = 10</h1>
<button id="runConccurency10">Run</button>
<ul id="conccurency10"></ul>
</section>
<br />
<section>
<h1>Concurrency = 1</h1>
<button id="runConccurency1">Run</button>
<ul id="conccurency1"></ul>
</section>
Babel + JSX
function promisePool(producer, concurrency = 10) {
return new Promise((resolve, reject) => {
let index = 0;
let finished = false;
let returnedValues = [];
let nbInstances = concurrency;
let mainPromise = Promise.resolve();
function onError(err) {
if (!finished) {
finished = true;
reject(err);
}
}
function onSuccess(value) {
returnedValues.push(value);
if (!finished) {
if (nbInstances < concurrency) {
nbInstances++;
process();
}
}
}
function process() {
while (!finished && nbInstances > 0) {
let lastPromise = producer(index);
index++;
nbInstances--;
if (!lastPromise) {
mainPromise
.then(() => {
resolve(returnedValues);
})
.catch(onError);
} else {
mainPromise = mainPromise
.then(() => {
return lastPromise
.then(onSuccess)
.catch(onError);
});
}
}
}
process();
});
}
let ulConccurency1Element = document.querySelector('#conccurency1');
let ulConccurency3Element = document.querySelector('#conccurency3');
let ulConccurency10Element = document.querySelector('#conccurency10');
document.querySelector('#runConccurency1').addEventListener('click', event => {
event.preventDefault();
ulConccurency1Element.innerHTML = '';
event.target.disabled = true;
let html = '';
promisePool(
index => {
if (index > 20) {
return null;
}
return new Promise(resolve => {
setTimeout(
() => {
let liElement = document.createElement('li');
liElement.innerText = `Item ${index}`;
ulConccurency1Element.appendChild(liElement);
...