2016-05-06 93 views
2

我正在努力围绕在一起链接我的头,承诺达到预期的结果。返回由链式javascript承诺创建的对象

简要背景: 我使用Ionic2(基于Angular2)创建移动应用程序。数据持久性基于SQLite。为了重新构建一个包含嵌套数组的复杂对象,我需要链接一些数据库调用。

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,取得并从附加表追加及其相关属性。我希望在将结果传递回来之前重建整个对象。

但是,目前,对象被传回,然后随着时间的推移,一旦每次额外的呼叫完成,就会添加属性。

我真的很感激,如果有人可以告诉我如何将这些链接在一起,以便控制器调用'buildObjectFromID'得到一个完整的对象。

非常感谢。

回答

1

两个变化可以使:

  1. 记住then返回一个新的承诺。由于您已有db.getEventWithCMSID的承诺,因此根本不需要使用new Promise,只需使用您从then那里获得的那个。一般来说,在达到new Promise之前,考虑一下你是否已经有了一份工作。

  2. 要等待所有下属操作完成,请使用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; 
     }); 
    }); 
} 

Live Example on Babel's REPL(为简便起见,我离开了两个下属的电话,只包括旗帜和图像)

也具有传播失败的优势,您的原始代码没有执行的操作(例如,如果getBannerForOwner失败,会发生什么情况)。

Live Example on Babel's REPL demonstrating failure

+0

非常感谢您的快速回复T.J. –

+0

您的解决方案非常深入。我非常感激。这解决了我以正确的顺序构建对象并返回完整对象的问题,但是,buildObjectFromID的调用方法也是Promise,我仍然遇到问题。我应该提出另一个问题,或更新我的原始? –

+0

@PhillipHartin:很高兴有帮助。由于这是非常新的信息,并且在这个问题上已经有两个答案,所以我会说你的本能反而开了一个新问题,可能是最好的。 –

1

我会充分利用Promise.all方法和链不同的承诺是这样的:

buildObjectFromID(id) { 
    let db = new DBHelper(); 

    // Get the event object from id 
    return db.getEventWithCMSID(id).then(event => { 
    return Promise.all([ 
     event, 
     db.getBannerForOwner(event.cmsId), 
     db.getImagesForOwner(event.cmsId), 
     db.getProfilePicturesForOwner(event.cmsId), 
     db.getLogosForOwner(event.cmsId) 
    ]); 
    }).then(result => { 
    let event = result[0]; 
    let banner = result[1]; 
    let images = result[2]; 
    let logos = result[3]; 

    event.banner = banner; 
    event.images = images; 
    event.profilepicture = profilepictures; 
    event.logos = logos; 
    return event; 
    }); 
}