在 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.forEach
是 Array.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;
});
});
我在正确处理各种承诺的响应时遇到了一些问题。
简要背景:我正在使用 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.forEach
是 Array.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;
});
});