mongodb的查询修改优化
发布于 7 年前 作者 ray1888 3412 次浏览 来自 问答

因为不是专门写node的,就想请问一下node社区对于我这个情景有没有好的优化方案。目前的场景是经常有业务需要先查了之后获取某个字段来改查询修改另一个表的相关字段。如

group.find().then((results)=>{
     var saveArray = new Array()
     for(result in results){   // result 拥有group_name 和users , users字段里面的是username
	      let group_object = {}
		  group_object["group_name"]= result['group_name']
		  user.find({"name":{"$in":result['users']}).then((name_list)=>{
		  	group_object['users'] = name_list
		  	saveArray.push(group_object )  // 此处users是一个array
		  },(err)=>{
		      reject(err)
		  } 
	 }
	 resolve(saveArray)
},(err)=>{
  reject(err)
})

这样的写法明显是有问题,因为for里面异步会被忽略,如果达到我这个逻辑的效果?

7 回复

其实是想通过这个问题去问,node里面如果处理异步和循环,因为只是目前在公司兼着写node,平时写python为主,不太习惯同步逻辑写成异步,所以求教一下

const saveArray = []

try {
    const results = await group.find()
    for (const result in results) {
        const name_list = await user.find({
            name: { $in: result.users }
        })
        saveArray.push({
            group_name: result.group_name,
            users: name_list
        })
    }
} catch (err) {
    console.log(err)
}

return saveArray

@XiaozhongLiu 如果不用async、await可以实现吗?因为对接的代码用的比较多的是promise的东西

@ray1888 基础要打牢, 不然这些问题烦死你. MDN上原话: The return value of an async function is implicitly wrapped in Promise.resolve. 所以下面的async function返回的就是一个promise.

async function foo() {
    const saveArray = []

    const results = await group.find()
    for (const result in results) {
        const name_list = await user.find({
            name: { $in: result.users }
        })
        saveArray.push({
            group_name: result.group_name,
            users: name_list
        })
    }

    return saveArray
}

这个场景可以用async

group.find().then((results)=>{ return Promise.all(results.map(result=> { let group_object = {}; group_object[“group_name”]= result[‘group_name’]; return user.find({“name”:{"$in":result[‘users’]}}).then((name_list)=>{ group_object[‘users’] = name_list return group_object; }); })) }).then(resultArray=> console.log(resultArray), (err)=> console.log(err)); 感觉可以用 Promise.all解决你的需求 。可以试一下

可以用promise-synchronizer模块把promise包装成同步的形式,在用async await,这样代码逻辑会清晰很多。

回到顶部