every Bit
every Bit

Reputation: 399

NodeJS - Promise.all() with array promise not return as expected

I'm developing a nodeJS application and I have some following code :

let all_result = await Promise.all([list_agrees,list_disagrees]);
    list_agrees = await Promise.all(list_agrees);
    list_disagrees = await Promise.all(list_disagrees);        

res.json({
    result_1:all_result,
    result_2: {
        list_agrees,
        list_disagrees
    }
});

Hi, here is what list_agrees and list_disagrees came from (and UserHelper.getUserBasicInfor() returns a promise)

list_agrees = list_agrees.map(async function(id_user){ 
  return await UserHelper.getUserBasicInfor(req,id_user);
}); 

list_disagrees = list_disagrees.map(async function(id_user){ 
  return await UserHelper.getUserBasicInfor(req,id_user); 
});

now what I got when I received response is

{
    "result_1": [
        [
            {}
        ],
        [
            {}
        ]
    ],
    "result_2": {
        "list_agrees": [
            {
                "avatar_thumbnail": null,
                "full_name": "Đạt Tô",
                "nick_name": "Gầy lọ"
            }
        ],
        "list_disagrees": [
            {
                "avatar_thumbnail": null,
                "full_name": "Gola User ",
                "nick_name": null
            }
        ]
    }
}

I don't know why Promise.all([list_agrees,list_disagress]) have not return the result as I expected!

Upvotes: 1

Views: 86

Answers (1)

Phil
Phil

Reputation: 164767

Promise.all() works on an iterable collection of promises.

Your issue is that both list_agrees and list_disagrees are arrays of promises and not promises themselves.

I would recommend something like this (without overwriting the original arrays)

const agrees = Promise.all(list_agrees.map(id_user =>
    UserHelper.getUserBasicInfor(req, id_user)))
const disagrees = Promise.all(list_disagrees.map(id_user =>
    UserHelper.getUserBasicInfor(req, id_user)))

Now agrees and disagrees are each promises that will resolve when each UserHelper.getUserBasicInfor() call resolves.

There's no need to use async functions in the mapping since your UserHelper.getUserBasicInfor() returns a promise anyway.

Now you can use

const all_result = await Promise.all([agrees, disagrees])
const [agrees_result, disagrees_result] = all_result
res.json({
  result_1:all_result,
  result_2: {
    list_agrees: agrees_result,
    list_disagrees: disagrees_result
  }
})

Upvotes: 2

Related Questions