返回由链接的javascript承诺创建的对象 [英] Returning objects created by chained javascript promises

查看:151
本文介绍了返回由链接的javascript承诺创建的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力将我的脑袋缠绕在一起,以实现预期的结果。

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.

非常感谢。

推荐答案

您可以进行两项更改:


  1. 请记住然后会返回新的承诺。由于您已经从 db.getEventWithCMSID 获得了承诺,因此您根本不需要使用 new Promise ,只需使用你从那个调用然后获得的那个。一般来说,在达到新承诺之前,请考虑您是否已经使用过。

  1. Remember that then returns a new promise. Since you already have a promise from db.getEventWithCMSID, you don't need to use new Promise at all, just use the one you get from calling then on that one. In general, before reaching for new 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).

实例关于Babel的REPL演示失败

Live Example on Babel's REPL demonstrating failure

这篇关于返回由链接的javascript承诺创建的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆