[英]How do I return the result from promise to map function
我有一个JavaScript诺言,我想在其中返回比映射第二个诺言更容易看到的map函数值。 我知道我无法从promise中返回价值,但是我问是否有更好的解决方案。 谢谢
我的代码:
const _ = require('lodash')
Boom = require('boom'),
When = require('when'),
User = require('../../models/user');
var users;
/**
* Contact core functionality
*/
users = {
/**
* Find user by id
*
* @param {id} user id
* @returns {Promise(User)} User
*/
findById: (id) => {
if (_.isEmpty(id)) {
return When.reject(Boom.badRequest('User id missing.'))
}
return User.get(id).run().then( (user) => {
if (user) {
return When.resolve(user)
}
return When.reject(Boom.notFound('No user registered with provided id.'))
}).error((error) => {
return When.reject(error)
});
},
/**
* Returns all contacts of user from database
* @returns [{Promise(Contact)}] contacts
*/
findContacts: (userId) => {
if (_.isEmpty(userId)) {
return When.reject(Boom.badRequest('User id missing.'))
}
return User.get(userId).run().then( (user) => {
if (user) {
if(_.isObject(user.contacts)){
user.contacts = _.map(user.contacts, (contact) => {
this.findById.then((user) => {
contact.user = user
})
return contact
})
return When.resolve(user.contacts)
}
return When.reject(Boom.notFound('No contacts registered with provided user.'));
}
}).error((error) => {
return When.reject(error)
})
},
}
和这里的问题:
user.contacts = _map(user.contacts, (contact) => {
this.findById.then((user) => {
contact.user = user
})
return contact
})
由于使用的是Promise库,因此应使用其自己的迭代器(例如map
和reduce
)来处理数组。
不过,在这里要注意的一件非常重要的事情是,当map
是“机会性地”运行(并行运行所有内容)时,而reduce
则是无重叠的串行运行。 换句话说,如果您有一个由1000个用户组成的数组,则map
将(可能)一次向您的数据库发送1000个请求,而reduce
直到依次完成每个数据库请求后才会完成。
因此您的代码可能如下所示:
// This mutates user.contacts, so you don't need to worry about the
// 'initial value' in your reducer function
When.reduce(user.contacts, (carry, contact) => {
return this.findById.then((user) => {
contact.user = user
})
});
如果确实有大量用户要处理,则将数据分块成较小的,合理大小的数组可能更有意义。 您将reduce
块并在每个数据块中map
用户。 这意味着该阵列的处理速度可能比串行处理快得多,但是没有任何浪费数据库的风险。
编辑
// This mutates user.contacts, so you don't need to worry about the
// 'initial value' in your reducer function
// It also returns the array of users as `allContacts`
var allContacts = When.reduce(user.contacts, (carry, contact) => {
return this.findById.then((user) => {
contact.user = user
carry.push(user);
return carry;
})
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.