Jouant avec JS moderne et s'est coincé un peu avec ce qui suit.Besoin de conseils sur Promises.all imbriqué
Envisagez d'avoir un système ExtSystem accessible via une API HTTP et une instance Mongo locale. Ils contiennent tous deux des objets avec name
et id
.
Pour Mongo J'utilise mongoose
avec le modèle ObjectSchema
({_id, sourceId, name, internalParam}
) où sourceId
égal à id
de ExtSystem et internalParam
existe seulement dans mon application. Pour ExtSystem il y a 2 méthodes de retour request.js
Promise:
- ExtSystem.all retourne un tableau de ids
[id, id, id]
- se
{id, name}
objet retourne ExtSystem.get
Il y a aussi une fonction globale errHandler
qui peut gérer erreurs à la fois request.js
et mongoose
promesses. Le but à atteindre est de synchroniser Mongo avec ExtSystem: mettre à jour tous les objets de ExtSystem dans Mongo et supprimer ceux présents dans ExtSystem de Mongo.
Ce que je suis venu avec:
ExtSystem.all().then(body => {
let basket = []; // will store all promises for both ExtSystem and Mongo requests
basket.push(...body.map(o => ExtSystem.get(o.id));
basket.push(ObjectSchema.find({}, 'sourceId'));
Promise.all(basket).then(basketDoc => {
let mongoObjects = {}, extObjects = {};
basketDoc.pop().forEach(o => mongoObjects[o.sourceId] = o._id); // Mongo retuns array of {_id, sourceId } objects
basketDoc.forEach(o => { // ExtSystem returns array of {id, name} objects
extObjects[o.id] = {
sourceId: o.id,
name: o.name
}
});
let esSet = new Set(Object.keys(extObjects));
let mongoDeleteIds = Object.keys(mongoObjects).filter(oId => !esSet.has(oId)); // Set.has is faster than Array.indexOf
let syncPromises = [];
syncPromises.push(...Object.keys(extObjects).map(oId => ObjectSchema.findOneAndUpdate({ sourceId: extObjects[oId].sourceId }, extObjects[oId], { upsert: true, new: true })));
syncPromises.push(...mongoDeleteIds.map(oId => ObjectSchema.remove({_id: oId})));
Promise.all(syncPromises).then(_ => { // I don't need results, only the moment when sync is complete
ObjectSchema.find().then(doc => { // return actual objects from Mongo
someBusinessLogic(doc);
}).catch(errHandler);
}).catch(errHandler);
}).catch(errHandler);
}).catch(errHandler);
donc j'ai encore 4 emboîtées Promise Résout et manquant probablement quelque chose. Existe-t-il un meilleur moyen d'y parvenir avec un code moins complexe?