Si vous savez comment les itérateurs fonctionnent et comment ils sont consommés, vous n'aurez pas besoin d'une bibliothèque supplémentaire, car il peut devenir très facile de construire votre propre concurrence vous-même. Laissez-moi vous montrer :
/* [Symbol.iterator]() is equivalent to .values()
const iterator = [1,2,3][Symbol.iterator]() */
const iterator = [1,2,3].values()
// loop over all items with for..of
for (const x of iterator) {
console.log('x:', x)
// notices how this loop continues the same iterator
// and consumes the rest of the iterator, making the
// outer loop not logging any more x's
for (const y of iterator) {
console.log('y:', y)
}
}
Nous pouvons utiliser le même itérateur et le partager entre les travailleurs.
Si vous aviez utilisé .entries()
au lieu de .values()
vous auriez obtenu un tableau 2D avec [[index, value]]
ce que je vais démontrer ci-dessous avec une concurrence de 2
const sleep = t => new Promise(rs => setTimeout(rs, t))
async function doWork(iterator) {
for (let [index, item] of iterator) {
await sleep(1000)
console.log(index + ': ' + item)
}
}
const iterator = Array.from('abcdefghij').entries()
const workers = new Array(2).fill(iterator).map(doWork)
// ^--- starts two workers sharing the same iterator
Promise.allSettled(workers).then(() => console.log('done'))
L'avantage est que vous pouvez avoir une fonction de générateur au lieu de tout préparer en même temps.
Ce qui est encore plus génial, c'est que vous pouvez faire stream.Readable.from(iterator)
dans node (et éventuellement dans les flux whatwg aussi). et avec ReadbleStream transférable, cela rend ce potentiel très utile dans la fonctionnalité si vous travaillez avec des web workers aussi pour les performances
Note : le différent de ce comparé à l'exemple async-pool c'est qu'il crée deux travailleurs, de sorte que si l'un d'eux lance une erreur pour une raison quelconque à l'index 5, cela n'empêchera pas l'autre travailleur de faire le reste. Vous passez donc de 2 concurrences à 1 (et cela ne s'arrêtera pas là). Je vous conseille donc d'attraper toutes les erreurs à l'intérieur de l'élément doWork
fonction
2 votes
Duplicata possible de Limiter la concurrence de la promesse en cours d'exécution
5 votes
N'oubliez pas que
Promise.all
gère la promesse de progression - les promesses le font elles-mêmes,Promise.all
les attend.3 votes
Évitez les
Promise
anti-modèle de constructeur !1 votes
gist.github.com/alexpsi/