【求助】nodejs 中 的map 如何才能 async 调用
发布于 4 年前 作者 pengliheng 6006 次浏览 来自 问答

额 ,情况是这样的,我用的mongodb数据库,koa-socket +koa 后端用的 我有一个json储存在数据库 其中的groups 是我加入的群id,现在我想通过map函数将groups里面的id 替换成{name:"...",avatar_url:"..."}这样的格式

{
    "_id" : "14994",
    "friends" : [],
    "groups" : [ 
        "5a0ed21b075e173878e8c17c",
		"5a0ed22332f23f32f328e23ffc"
    ],
    "github" : {
        "login" : "pheng",
        "id" : 143,
        "avatar_url" : "http"
    }
}

于是我通过map循环,通过查询我的数据库group详情,函数如下

myInfo.groups = myInfo.groups.map(async id =>{
    let groupInfo = await Group.findOne({
        _id:id
    })
    console.log(groupInfo);
    return {
        name:groupInfo.name,
        avatar_url:groupInfo.avatar_url
    }
})

返回结果是这样的 Promise { <pending> } 。。。 我觉得可能是map不支持异步调用,我想重写map,

Array.prototype.myMap = async function(callback) {
    let result = []
    this.forEach((item, index, arr) => {
        result.push(callback(item, index, arr));
    })
    return result;
}
myInfo.groups = myInfo.groups.myMap(async id =>{
    let groupInfo = await Group.findOne({
        _id:id
    })
    console.log(groupInfo);
    return {
        name:groupInfo.name,
        avatar_url:groupInfo.avatar_url
    }
})

返回结果Promise { [Array] } 额,如何才能将group里面的id 优雅的替换成具体group内容。。。我的group具体内容存在mongodb数据库另外一个地方。。。

3 回复

因为你的map函数,返回的是promise。

所以myInfo.groups的值为 Array<Promise>

在一个,不要在原生对象的原型链上添加方法。

只要一个Promise.all方法包住 Array<Promise>即可.

改成这样…

  myInfo.groups = await Promise.all(myInfo.groups.map(async id => {
    let groupInfo = await Group.findOne({
      _id: id
    });
    console.log(groupInfo);
    return {
      name: groupInfo.name,
      avatar_url: groupInfo.avatar_url
    };
  }));

厉害了,亲测有效, Promise.all完美解决我的问题,

@axetroy 这么写,不是同时执行myInfo.groups.length个查询吧?是串行的吧?

回到顶部