使用 Array.map 时嵌套承诺,使用 Promise.all 但仍然无法正常工作
Posted
技术标签:
【中文标题】使用 Array.map 时嵌套承诺,使用 Promise.all 但仍然无法正常工作【英文标题】:Nested promises while using Array.map, using Promise.all but still not working 【发布时间】:2017-08-28 04:10:29 【问题描述】:我的头撞墙已经有一段时间了。我有一些节点代码可以提取一堆 googlecalendar 事件,然后将它们映射到不同的对象结构上以在我的 webapp 中使用...作为其中的一部分,我需要将 google 日历事件中的用户与我的 webapp 中的用户匹配数据库。代码如下:
router.post('/getCalendar', function(req,res)
// authentication
var oauth2Client = getOAuthClient();
var session = req.session;
oauth2Client.setCredentials(
access_token: req.user.google.token,
refresh_token: req.user.google.refreshToken,
expiry_date: true
)
var p = new Promise(function (resolve, reject)
// get the next 20 calendar events
var calendar = google.calendar('v3');
calendar.events.list(
auth: oauth2Client,
calendarId: 'primary',
timeMin: (new Date()).toISOString(),
maxResults: 20,
singleEvents: true,
orderBy: 'startTime'
, function(err, response)
if (err) console.log('err',err)
// displays all the events
if (response) console.log('response',response)
if(response)
var events = response.items;
resolve(events || err);
);
).then(function (data)
var newdata = data.map(function(item)
// create the new object structure and populate with some details
newObj =
_id: item.id,
_title: item.summary,
group: [req.headers.group],
fields: [],
assignedTo: [],
google: "calendar",
googledata: item,
_category: []
var extendedFields =
// get the list of attendees
attendees = item.attendees.map(function(user)
var attendee = user.email;
return attendee;
)
// pulls the user information for each attendee using promises
var promises = attendees.map(function(email)
return new Promise(function(resolve, reject)
// data is in a mongodb, using mongoose
User.findOne('google.email': email).exec(function (err, user)
if (err) return resolve(null);
resolve(user); //not using reject at all so the Promise.all shouldn't fail
);
)
)
Promise.all(promises)
.then(function(value)
value.forEach(function(user)
if(promise !== null)
newObj.assignedTo.push(user);
);
return newObj
).catch((error) => console.log(error))
)
res.json(newdata)
)
);
我正在使用 Promise.all 等到所有承诺都已解决,但它似乎在完成第一项之前移动到 data
数组中的下一项。欢迎任何指导。如果需要更多详细信息,请告诉我。
谢谢。
【问题讨论】:
没有回复时别忘了reject
data
数组也需要使用 Promise.all
和 map
@Bergi - 我认为当我使用reject
时,Promise.all
会失败...我也不确定如何将 Promise.all 用于map
和data
正如你所建议的。您能否提供更多解释或示例?
我的意思是 calendar.events.list
调用 - 如果你不履行承诺(履行或拒绝),它将永远挂起。
你已经为 attendees
做的很好 - 现在只需为 data
数组做同样的事情。 return
来自map
回调的“内部”Promise.all(…)
承诺,因此newdata
又是一组承诺
【参考方案1】:
返回最后一个 Promise.all 的承诺。
return Promise.all(promises)
.then(function(value)
value.forEach(function(user)
// user !== null ?
if(promise !== null)
newObj.assignedTo.push(user);
);
return newObj
)
.catch((error) => console.log(error))
在新数据上使用 Promise.all。
Promise.all(newdata)
.then(function (newObjs)
// newObjs is the Array of newObj in your code
res.json(newObjs);
)
.catch(function (err)
console.log(err);
);
【讨论】:
以上是关于使用 Array.map 时嵌套承诺,使用 Promise.all 但仍然无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章