简体   繁体   English

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

[英]How do I return the result from promise to map function

I have a javascript promise where I want to return the value to map function that Easier to see than explain the problem with second promise. 我有一个JavaScript诺言,我想在其中返回比映射第二个诺言更容易看到的map函数值。 I know I can not return value from inside of promise but i ask if there any better solution to that. 我知道我无法从promise中返回价值,但是我问是否有更好的解决方案。 Thanks 谢谢

My code: 我的代码:

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)
        })
    },
}

And the issue here: 和这里的问题:

                user.contacts = _map(user.contacts, (contact) => {
                    this.findById.then((user) => {
                        contact.user = user
                    })
                    return contact
                })

Since you are using the When promise library, you should use its own iterators, such as map and reduce , to process your arrays. 由于使用的是Promise库,因此应使用其自己的迭代器(例如mapreduce )来处理数组。

One thing that is incredibly important to note here though is that in When map runs "opportunistically" (runs everything at once in parallel) while reduce runs in serial with no overlaps. 不过,在这里要注意的一件非常重要的事情是,当map是“机会性地”运行(并行运行所有内容)时,而reduce则是无重叠的串行运行。 In other words, if you have an array of 1000 users, map will (probably) send 1000 requests to your database at once, while reduce won't finish until it has completed each database request in turn. 换句话说,如果您有一个由1000个用户组成的数组,则map将(可能)一次向您的数据库发送1000个请求,而reduce直到依次完成每个数据库请求后才会完成。

So your code might look like this: 因此您的代码可能如下所示:

// 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
     })
 });

If you do have a ton of users to process, it might make more sense to chunk your data into an array of smaller, reasonably sized arrays; 如果确实有大量用户要处理,则将数据分块成较小的,合理大小的数组可能更有意义。 you would reduce the chunks and map the users in each chunk. 您将reduce块并在每个数据块中map用户。 This would mean the array could be processed much faster than when done in serial, but without any risk of hosing your database. 这意味着该阵列的处理速度可能比串行处理快得多,但是没有任何浪费数据库的风险。

edit 编辑

// 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