在 javascript promises 中正确使用 then

Correct use of then in javascript promises

我在正确处理各种承诺的响应时遇到了一些问题。

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

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

,此方法运行良好

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

日程-controller.js

 getSchedule() {

    let db = new DBHelper();
    let scheduleController = new ScheduleController();

    return db.getScheduledEvents().then(scheduledEvents => {
      //  For each scheduled event, get the related object
      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;
      });
    });
  }


buildObjectFromID(id) {

    let db = new DBHelper();
    return db.getSpeakerWithCMSID(id).then(speaker => {
      return Promise.all([
        db.getBannerForOwner(speaker.cmsId).then(banner => {
          speaker.banner = banner;
        }),
        db.getImagesForOwner(speaker.cmsId).then(images => {
          speaker.images = images;
        }),
        db.getProfilePicturesForOwner(speaker.cmsId).then(profilepictures => {
          speaker.profilepicture = profilepictures;
        })
      ]).then(() => {
        return speaker;
      });
    });

如果有任何帮助或指导,我将不胜感激。谢谢。

您忘记了 return scheduledEvents.forEach().then() 的结果,否则 getSchedule() 所承诺的 return 将立即解析为 undefined

(我假设 scheduledEvents.forEachArray.forEach 的某种抽象,一旦迭代完成,return 就是一个 Promise,而不是 Array.forEach 本身,否则它的结果不会'甚至没有 then 方法。)

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 不可能有任何特别之处并且仍然有效。即使 returned 一个 Promise 是一个抽象,你似乎也在 lambda 内部做异步工作而没有 return 那些 promise。所以我开始认为这只是常规 Array.forEach 而你也犯了一个错误。

在那种情况下,您想要的是 Array.map 创建一组您要在各个 scheduledEvents 上执行的工作的承诺,然后用 Promise.all[=24= 等待它们]

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;
  });
});