玩弄现代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套无极解决,可能失去了一些东西。有没有一种最简单的方式来实现这个代码不复杂?