猫鼬顺序承诺(mongoose sequential promises)

编程入门 行业动态 更新时间:2024-10-21 18:38:04
猫鼬顺序承诺(mongoose sequential promises)

我正在尝试顺序执行一些动态查询,但出于任何原因,下一个代码无法实现所需的行为。

var createEvent = function (user, notification) { var action, query; query = { agent: notification.agent, story: notification.story, type: notification.type }; action = { agent: notification.agent, story: notification.story, type: notification.type, ts: notification.ts }; return mongoose.model('Event').findOne(query).exec() .then(function (response) { if (response === null) { return mongoose.model('Event').create(action) .then(function (response) { return mongoose.model('User').findByIdAndUpdate(user, { $push: { notifications: { _id: response._id }}}); }); } return mongoose.model('User').findByIdAndUpdate(user, { $push: { notifications: { _id: notification._id }}}).exec(); }); setTimeout(resolve, 3000); }; var moveNotifications = function (users) { var promises = []; users.map(function (user) { if (user.notifications.length > 0) { user.notifications.map(function (notification) { promises.push(createEvent(user._id, notification)); }); } }); Promise.each(promises, function (queue_item) { return queue_item(); }); };

有人能帮帮我吗?

I'm trying to do some dynamic queries sequential but for any reason, the next code doesn't fulfil that desired behaviour.

var createEvent = function (user, notification) { var action, query; query = { agent: notification.agent, story: notification.story, type: notification.type }; action = { agent: notification.agent, story: notification.story, type: notification.type, ts: notification.ts }; return mongoose.model('Event').findOne(query).exec() .then(function (response) { if (response === null) { return mongoose.model('Event').create(action) .then(function (response) { return mongoose.model('User').findByIdAndUpdate(user, { $push: { notifications: { _id: response._id }}}); }); } return mongoose.model('User').findByIdAndUpdate(user, { $push: { notifications: { _id: notification._id }}}).exec(); }); setTimeout(resolve, 3000); }; var moveNotifications = function (users) { var promises = []; users.map(function (user) { if (user.notifications.length > 0) { user.notifications.map(function (notification) { promises.push(createEvent(user._id, notification)); }); } }); Promise.each(promises, function (queue_item) { return queue_item(); }); };

Could someone help me?

最满意答案

当您在嵌套的Array#map循环中调用createEvent ,您将立即启动所有查询 - 您要做的只是获取一个id和notification数组,以便稍后传递给Promsise.each中的Promsise.each

注意:不确定为什么使用Array#map ,因为你永远不会从map回调中返回任何内容 - 你基本上是在做Array#forEach

var moveNotifications = function(users) { var items = []; users.forEach(function(user) { if (user.notifications.length > 0) { user.notifications.forEach(function(notification) { items.push({id: user._id, notification: notification}); }); } }); return Promise.each(events, function(item) { return createEvent(item._id, item.notification); }); }

或者,使用Array#concat来展平通过正确使用(嵌套) Array#map返回的2级数组,可以获得相同的结果

var moveNotifications = function(users) { return Promise.each([].concat.apply([], users.map(function(user) { return user.notifications.map(function(notification) { return {id: user._id, notification: notification}; }); })), function(item) { return createEvent(item._id, item.notification); }); }

使用以下ES2015语法可以更加简洁地进行上述操作:

arrow functions => 传播运营商... 简写对象属性名{a, b, c} 解构分配 - 参数上下文匹配({a, b, c}) =>
var moveNotifications = users => Promise.each([].concat(...users.map(user => user.notifications.map(notification => ({id: user._id, notification})) )), ({id, notification}) => createEvent(id, notification) );

极端的ES2016单线版:p

var moveNotifications = users => Promise.each([].concat(...users.map(user => user.notifications.map(notification => ({id: user._id, notification})))), ({id, notification}) => createEvent(id, notification));

As you are calling createEvent inside the nested Array#map loops, you are starting all the queries at once - what you want to do is just get an array of id and notification to later pass to createEvent in Promsise.each

Note: Not sure why you use Array#map, as you never return anything from the map callback - you're basically doing Array#forEach

var moveNotifications = function(users) { var items = []; users.forEach(function(user) { if (user.notifications.length > 0) { user.notifications.forEach(function(notification) { items.push({id: user._id, notification: notification}); }); } }); return Promise.each(events, function(item) { return createEvent(item._id, item.notification); }); }

Alternatively, using Array#concat to flatten a 2 level array that is returned by using (nested) Array#map correctly you can achieve the same result

var moveNotifications = function(users) { return Promise.each([].concat.apply([], users.map(function(user) { return user.notifications.map(function(notification) { return {id: user._id, notification: notification}; }); })), function(item) { return createEvent(item._id, item.notification); }); }

The above is easily made even more concise using the following ES2015 syntax:

arrow functions => spread operator ... shorthand Object property names {a, b, c} Destructuring Assignment - Parameter Context Matching ({a, b, c}) =>
var moveNotifications = users => Promise.each([].concat(...users.map(user => user.notifications.map(notification => ({id: user._id, notification})) )), ({id, notification}) => createEvent(id, notification) );

The extreme ES2016 one liner version :p

var moveNotifications = users => Promise.each([].concat(...users.map(user => user.notifications.map(notification => ({id: user._id, notification})))), ({id, notification}) => createEvent(id, notification));

更多推荐

本文发布于:2023-08-04 12:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1416072.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:顺序   mongoose   promises   sequential

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!