玩弄現代JS,並陷入了一些與以下幾點。需要關於嵌套Promises.all的建議
考慮通過一些HTTP API和本地Mongo實例來訪問ExtSystem。它們都包含name
和id
的對象。
對於蒙戈我使用mongoose
與ObjectSchema
模型({_id, sourceId, name, internalParam}
)其中sourceId
等於id
從ExtSystem和internalParam
只存在於我的應用程序。對於ExtSystem有2種方法返回request.js
無極:
- ExtSystem.all返回ID的數組
[id, id, id]
- ExtSystem.get返回對象本身
{id, name}
還有一個全局函數errHandler
它可以處理來自request.js
和mongoose
承諾的錯誤。要實現的目標是將Mongo與ExtSystem同步:在Mongo中更新ExtSystem中的所有對象,並從Mongo中刪除不再存在於ExtSystem中的對象。
我想出了:
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);
所以我仍然有4套無極解決,可能失去了一些東西。有沒有一種最簡單的方式來實現這個代碼不復雜?