2016-09-19 7 views
0

Je crée des données de base pour ma base de données. La fonction de démarrage est co-enveloppé générateur (https://www.npmjs.com/package/co):Paralléliser l'exécution de Promise contenant un générateur co-emballé

createSeedData() { 
    co(function *() { 
    [...] 
    } 
} 

À un moment donné, je suis en train de créer 40 enchères avec une offre chacun. Jusqu'à présent j'avais une boucle for comme ceci:

for (let i = 0; i <= 40; i++) { 
    let auction = yield auction.create({ 
    [...] 
    }) // Async creation of model and persisting it in db 
    yield bid.create({ 
    auction: auction.id 
    [...] 
    }) 
} 

Maintenant, j'aimerais créer la vente aux enchères en parallèle, mais je ne peux pas tout à fait le faire fonctionner.

co prend en charge l'exécution parallèle lorsque le rendement est utilisé avec des tableaux.

Cependant, j'ai encore besoin de créer d'abord une facture, puis une enchère en utilisant le rendement.

J'ai essayé d'emballer ce qui précède dans une fonction Promise et une fonction interne de générateur co-enveloppé mais cela ne finit jamais l'exécution.

Comment puis-je résoudre ce problème? (si possible sans utiliser plus de paquets)

Voici ma tentative avec le générateur interne:

let promises = [] 
for (let i = 0; i <= 40; i++) { 
    promises.push(new Promise(
    co(function *(resolve, reject) { 
     let auction = yield auction.create({ 
     [...] 
     }) // Async creation of model and persisting it in db 

     yield bid.create({ 
     auction: auction.id 
     [...] 
     }) 
    ) 
    resolve() 
)) 
} 
yield invoicePromises 
+0

promesses faites aux sauvetage, en effet! S'il vous plaît nous montrer votre tentative avec le générateur interne. De plus, qu'est-ce que 'create' renvoie, utilise-t-il déjà des promesses? – Bergi

+0

@Bergi 'create' renvoie une promesse. J'ai ajouté le générateur interne. – Hedge

Répondre

1

Il n'y a pas besoin d'appeler new Promise (et il ne fonctionne pas parce que vous n'appelez resolve ou reject). Il suffit d'omettre cette partie, co() renvoie déjà une promesse:

let promises = []; 
for (let i = 0; i <= 40; i++) { 
    promises.push(co(function *() { 
    let auction = yield auction.create({ 
     [...] 
    }); // Async creation of model and persisting it in db 
    yield bid.create({ 
     auction: auction.id 
     [...] 
    }); 
)); 
} 
yield invoicePromises; 

Si vous ne souhaitez pas utiliser un générateur interne, vous pouvez faire l'enchaînement avec des promesses simples ainsi:

let promises = []; 
for (let i = 0; i <= 40; i++) { 
    promises.push(
    auction.create({ 
     [...] 
    }).then(auction => 
     bid.create({ 
     auction: auction.id 
     [...] 
     }); 
    ) 
); 
} 
yield Promise.all(invoicePromises); 
+0

Génial cela fonctionne. J'ai déjà eu un 'resolve()' dans mon code mais sans ajout explicite de Promise, c'est encore mieux. – Hedge

+0

Oui, l'introduire inutilement même est un [antipattern] (http://stackoverflow.com/q/23803743/1048572) - vous auriez besoin d'utiliser 'try {...} catch (e) {reject (e)}' dans le générateur ainsi de propager des erreurs – Bergi