javascriptnode.jspromisebluebirdes6-promise

Resolve all promises in an array of json - javascript


I need to resolve all promises in an array of json, like this:

let list = [
    { 
        id: 1,
        data: new Promise((resolve, reject) => {
            resolve('Cat')
        })
    },
    { 
        id: 2,
        data: new Promise((resolve, reject) => {
            resolve('Dog')
        })
    },
    { 
        id: 3,
        data: new Promise((resolve, reject) => {
            resolve('Mouse')
        })
    }
]

I use bluebird promises. I used a for cycle to iterate all items, I would know if there was some way more elegant.

Expected result:

[ { data: 'Cat', id: 1 },
  { data: 'Dog', id: 2 },
  { data: 'Mouse', id: 3 } ]

Solution

  • This should work, Promise.all and array.map like the others, but the result is correct

    let list = [
        { 
            id: 1,
            data: new Promise((resolve, reject) => {
                resolve('Cat')
            })
        },
        { 
            id: 2,
            data: new Promise((resolve, reject) => {
                resolve('Dog')
            })
        },
        { 
            id: 3,
            data: new Promise((resolve, reject) => {
                resolve('Mouse')
            })
        }
    ]    
    
    Promise.all(list.map(item => item.data.then(data => ({...item, data}))))
    // that's it, that's what you want, the rest is for show now
    .then(results => {
       console.log(results);
    });

    though, that's Native Promises ... you may want to look into Promise.props and/or Promise.map in bluebird for possibly simpler code yet

    It could well be as simple as

    Promise.map(list, Promise.props)
    .then(results => {
        console.log(results);
    });
    

    tested the above, and yes, it is that simple - the snippet below has my own version of Promise.map and Promise.props - and works (at least in this case) identically to bluebird

    Promise.props = obj => {
        const keys = Object.keys(obj);
        return Promise.all(Object.values(obj)).then(results => Object.assign({}, ...results.map((result, index) => ({[keys[index]]: result}))));
    };
    
    Promise.map = (array, fn, thisArg) => Promise.all(Array.from(array, (...args) => fn.apply(thisArg, args)));
    
    let list = [
        { 
            id: 1,
            data: new Promise((resolve, reject) => {
                resolve('Cat')
            })
        },
        { 
            id: 2,
            data: new Promise((resolve, reject) => {
                resolve('Dog')
            })
        },
        { 
            id: 3,
            data: new Promise((resolve, reject) => {
                resolve('Mouse')
            })
        }
    ]    
    
    Promise.map(list, Promise.props)
    .then(results => {
        console.log(results);
    });