在javascript承诺中正确使用then

时间:2016-05-06 16:24:16

标签: javascript ionic-framework promise ionic2

我有一些问题正确处理各种承诺的回应。

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

在下面的方法中,我正在获取ScheduledEvents列表。对于每个事件,我然后获取其关联的对象(显示在buildObjectFromID中) - >由于Returning objects created by chained javascript promises

,此方法效果很好

但是,当返回此对象时,我希望方法getSchedule()仅在forEach部分中处理完所有元素后才返回更新的列表。目前,似乎scheduleEvents对象立即返回,并且随着时间的推移实际更新,因为该方法继续执行。

时间表controller.js

<ui-select multiple tagging tagging-label="('new' email)" ng-model="emails" theme="bootstrap" sortable="true" ng-pattern="validEmail" required>
  <ui-select-choices repeat="email in emails track by emailId" refresh="refreshEmailAddresses($select.search)"
  refresh-delay="0">
  </ui-select-choices>
</ui-select>

我非常感谢任何帮助或方向。谢谢。

1 个答案:

答案 0 :(得分:2)

您忘记返回scheduledEvents.forEach().then()的结果。如果getSchedule()返回的承诺会立即解决undefined

(我假设scheduledEvents.forEachArray.forEach的一些抽象,它在迭代完成后返回一个Promise,而不是Array.forEach本身,否则它的结果甚至不会有then 1}}方法。)

return db.getScheduledEvents().then(scheduledEvents => {
  //  For each scheduled event, get the related object
  return scheduledEvents.forEach(scheduledEvent => {
    scheduleController.buildObjectFromId(scheduledEvent.id).then(relatedObject => {
      //update object with new property 
      scheduledEvent.data = relatedObject;
    });
  }).then(() => {
    //Once all properties have been updated, return updated array
    return scheduledEvents;
  });
});

(您也可以将() => { return foo; }替换为() => foo

实际上,我认为scheduledEvents.forEach没有任何特殊的东西可以使用。即使它是一个返回Promise的抽象,你似乎在lambda中做异步工作而不返回那些promise。所以我开始认为它只是常规的Array.forEach,你也犯了错误。

在这种情况下,你想要的是Array.map创建一个你想要对各个scheduledEvents执行的工作的promises数组,然后用Promise.all

等待它们全部
return db.getScheduledEvents().then(scheduledEvents => {
  //  For each scheduled event, get the related object
  return Promise.all(scheduledEvents.map(scheduledEvent => {
    return scheduleController.buildObjectFromId(scheduledEvent.id).then(relatedObject => {
      //update object with new property 
      scheduledEvent.data = relatedObject;
    });
  })).then(() => {
    //Once all properties have been updated, return updated array
    return scheduledEvents;
  });
});