我有一个http请求,它应该返回任务列表。然而,这些任务是以复杂的方式生成的。这就是它的工作原理。
- 从DB获取所有当前任务
- 过期的任务
- 从DB获取用户配置文件
- 如果用户没有配置文件,并且不存在创建配置文件的任务,则添加创建配置文件的任务
- 此外,对于用户拥有的每个子配置文件,如果还没有创建每日任务,则创建每日任务并将其保存到DB。
- 将所有任务返回给HTTP调用者
我不明白的是如何将日常任务所需的N个承诺添加到我的承诺链中。我还需要所有可用的数据,最后一个进程返回新创建的任务列表。我应该以某种方式嵌套承诺吗?
目前,我想象它是这样的:
var taskPromise = dbPromise(serverName, taskRequest, params);
var profilesPromise = dbPromise(serverName, profilesRequest, params);
Q.all([taskPromise, profilesPromise])
.then(function(arrayOfTasksAndProfiles){
//do calculations and create an object like {tasks:[], profile:profile, subprofiles:[]})
.then(function(currentDataObject) {
var deferred = Q.defer();
var newTasksToBeCreated = // make a list of all the new tasks I want to create
var promisesForNewTasks = [] // create an array of promises that save each of the new tasks to the server
Q.all(promisesForNewTasks)
.then(function(returnedIDsForNewTasks) {
// somehow match the returned IDs to the newTasksToBeCreated and add them on
currentDataObject.newTasks = newTasksToBeCreated
deferred.resolve(currentDataObject);
});)
.then(function(currentDataObject) {
// now that the currentDataObject has all the tasks from the DB, plus the new ones with their IDs, I can respond with that information
res.json(currentDataObject))
.done();
我必须多次调用DB来创建新任务,并且我需要返回那些附加到我从DB收到的其他任务的任务,我能看到的唯一方法是嵌套Q.all()调用。
"一定有更好的办法。"
只有一件事:不要创建需要手动解析的自定义deferred
。相反,只有then
处理程序中的return
;return
为.then()
调用的结果承诺。
.then(function(currentDataObject) {
var newTasksToBeCreated = // make a list of all the new tasks I want to create
var promisesForNewTasks = [] // create an array of promises that save each of the new tasks to the server
return Q.all(promisesForNewTasks)
// ^^^^^^
.then(function(returnedIDsForNewTasks) {
// somehow match the returned IDs to the newTasksToBeCreated and add them on
currentDataObject.newTasks = newTasksToBeCreated
return currentDataObject;
// ^^^^^^
});
})
否则,它看起来很好。如果在将返回的id与任务匹配时遇到问题,请不要这样做。相反,让每个promisesForNewTasks
解析使用自己的任务对象(与id结合)。