繁体   English   中英

如何将诺言的结果返回给地图函数

[英]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库,因此应使用其自己的迭代器(例如mapreduce )来处理数组。

不过,在这里要注意的一件非常重要的事情是,当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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM