返回由链接的javascript承诺创建的对象 [英] Returning objects created by chained javascript promises
问题描述
我正在努力将我的脑袋缠绕在一起,以实现预期的结果。
I am struggling to wrap my head around chaining together promises to achieve a desired result.
简要背景:
我正在使用Ionic2(基于Angular2)创建移动应用程序。数据持久性基于SQLite。为了重新构建包含嵌套数组的复杂对象,我需要将多个数据库调用链接在一起。
Brief background: I'm Using Ionic2 (based on Angular2) to create mobile app. Data persistence is based on SQLite. In order to re-build a complex object that contains nested arrays, I need to chain together a number of database calls.
buildObjectFromID(id) {
return new Promise(function (resolve, reject) {
let db = new DBHelper();
try {
// Get the event object from id
db.getEventWithCMSID(id).then(event => {
db.getBannerForOwner(event.cmsId).then(banner => {
event.banner = banner;
});
db.getImagesForOwner(event.cmsId).then(images => {
event.images = images;
});
db.getProfilePicturesForOwner(event.cmsId).then(profilepictures => {
event.profilepicture = profilepictures;
});
db.getLogosForOwner(event.cmsId).then(logos => {
event.logos = logos;
});
resolve(event);
});
}
catch
(err) {
reject({err: err});
}
}
);
}
此方法旨在从数据库中获取主对象,并使用它的ID ,从其他表中获取并附加其相关属性。我希望在将结果传回之前重新完成对象。
This method aims to fetch a main object from the database, and using it's ID, fetches and appends its related properties from additional tables. I wish to rebuild the object in it's entirety before passing the result back.
然而,此时,对象被传回,然后随着时间的推移,属性被添加一次每个额外的通话都已完成。
However, at the moment, the object is passed back and then over time the properties are added once each additional call is completed.
如果有人能告诉我如何将这些链接在一起,我会非常感激,以便调用'buildObjectFromID'的控制器获得一个完整的对象。
I would really appreciate if someone could inform me how I can chain these together, so that the controller calling 'buildObjectFromID' gets a complete object.
非常感谢。
推荐答案
您可以进行两项更改:
-
请记住
然后
会返回新的承诺。由于您已经从db.getEventWithCMSID
获得了承诺,因此您根本不需要使用new Promise
,只需使用你从那个调用然后
获得的那个。一般来说,在达到新承诺
之前,请考虑您是否已经使用过。
Remember that
then
returns a new promise. Since you already have a promise fromdb.getEventWithCMSID
, you don't need to usenew Promise
at all, just use the one you get from callingthen
on that one. In general, before reaching fornew Promise
, consider whether you already have one the work with.
要等待所有下属操作完成,请使用 Promise.all
。
To wait for all of your subordinate operations to complete, use Promise.all
.
所以:
buildObjectFromID(id) {
let db = new DBHelper();
return db.getEventWithCMSID(id).then(event => {
return Promise.all([
db.getBannerForOwner(event.cmsId).then(banner => {
event.banner = banner;
}),
db.getImagesForOwner(event.cmsId).then(images => {
event.images = images;
}),
db.getProfilePicturesForOwner(event.cmsId).then(profilepictures => {
event.profilepicture = profilepictures;
}),
db.getLogosForOwner(event.cmsId).then(logos => {
event.logos = logos;
})
]).then(() => {
return event;
});
});
}
实例关于Babel的REPL (为简洁起见,我遗漏了两个从属电话,只包括横幅和图片)
Live Example on Babel's REPL (for brevity I left out two of the subordinate calls, just include banner and images)
这也有传播失败的优势,原始代码没有这样做(考虑如果 getBannerForOwner会发生什么
失败,例如)。
That also has the advantage of propagating failures, which your original code didn't do (consider what happens if getBannerForOwner
fails, for instance).
Live Example on Babel's REPL demonstrating failure
这篇关于返回由链接的javascript承诺创建的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!