gpt4 book ai didi

javascript - 需要有关嵌套 Promises.all 的建议

转载 作者:行者123 更新时间:2023-11-30 09:30:05 25 4
gpt4 key购买 nike

尝试使用现代 JS,但遇到了以下问题。

考虑通过某些 HTTP API 和本地 Mongo 实例访问 ExtSystem。它们都包含具有 nameid 的对象。

对于 Mongo,我使用 mongooseObjectSchema 模型 ({_id, sourceId, name, internalParam}) 其中 sourceId 等于来自 ExtSystem 的 idinternalParam 仅存在于我的应用程序中。对于 ExtSystem,有 2 个方法返回 request.js Promise:

  • ExtSystem.all 返回 id 数组 [id, id, id]
  • ExtSystem.get 返回对象本身 {id, name}

还有一个全局函数 errHandler 可以处理来自 request.jsmongoose Promise 的错误。实现的目标是将 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 个嵌套的 Promise 解析并且可能遗漏了一些东西。是否有使用不太复杂的代码来实现此目的的最佳方法?

最佳答案

Promises 旨在摆脱厄运金字塔。如果您嵌套了 Promise,那么您就做错了。

Promises 允许您在调用中返回另一个 promise 以链接它们。所以不要这样做:

p1.then(stuff => {
p2.then(stuff =>{
...
});
});

你应该这样做

p1
.then(stuff => {
return p2;
}).then(stuff => {
return;
});

如果您有一些变量需要在未来的 promise 中访问,您可以将它们作为另一个 promise 包括在内,或者使用 this piece of code我刚才创建了一个包含全局可重用对象的 promise 。

Promise
.resolve({}) // creates global object for holding values
.then(obj => {
return pack(obj, taskPromiseA, "a", taskPromiseB, "b");
})
.then(obj => { // you can access results from A and B here
return pack(obj, taskPromiseC, "c");
})
.then(console.log); // you can access them all here

关于javascript - 需要有关嵌套 Promises.all 的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46844866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com