node中map函数同步执行
看到这样一句话 node中map()有一个特性:当其函数里面里面有回调它就变成异步;
我现在有一个这样的一个函数,遍历数组从mongodb中找出想要的数据。
function save(arr) {
let newArr = [];
arr.map((item) => {
Model.findOne({_id: item.id}, (err, data) => {
newArr.push(data)
// do something
})
});
console.log(newArr)
}
我不是知道如何将这个函数改为同步的,我想要得到一个有数据的newArr,而不是一个空数组,
请指教!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
一日吸猫,终身吸猫。一旦异步,就不要试图在其中混入同步的逻辑,这会极大地损失性能和造成各种问题。相反,你应该把所有同步的逻辑想办法改为异步的,这是使用异步编程的最基本要求,也是对同步编程思维方式最大的一个挑战。
异步的思维方式要求你找到合适的时间点触发合适的事件。比如你的场景可以这样理解:
arr
中的每个元素都可以找到一个对应的数据库文档_id
查询对应的记录(这就是map
里面做的事情)push
到newArr
之后再执行后续操作4的要求可以抽象为:同时执行n个操作,如何在n个操作都完成后再执行下面的操作。这是异步编程里面经常遇到的问题。因为经常遇到,所以肯定也已经有解决方案了:
这两个类库请挑一个仔细学习,都可以解决你的问题。因为这是使用异步编程必须跨过的一关,必须要你自己理解,我在这里不给具体的答案,请先尝试自己解决。
就事论事来说你的问题,无论是从效率还是便捷性上来说,其实你都做得太复杂了(当然不排除你是为了实验目的)。从解决问题的角度来说,建议直接使用
$in
:今天也遇到了同样的问题,不过跟你的场景不一样,我们其实只需要知道map函数遍历是立即执行的,即使你内部定义了async,并进行了await异步操作,但是map函数并不知道你什么时候返回完成状态的promise,所以理所当然的map函数最后返回的是一个promise对象数组。比如我遇到的场景是需要在已有的文章列表数据中,将标签字段的字符串(如; '1,2,3,5'id逗号隔开)关联标签表并获取标签名称合并到原来的文章列表数据中。这其中就需要遍历list并把标签ids取出并异步查询同时将结果合并到每一条列表数据里面。此时代码应该是这样的
这里可以看到的是map将每一条数据和tagInfo进行了合并,然后一起返回,由于上面说到的原因,所以这里得到的result应该是
知道了数组里面装着的是promise对象我们要获取也很简单,不要忘了async/await也是建立在promise的基础上的,所以这里不妨利用promise.all方法解决问题
这样下来便拿到了list数据,同时也将结果返回给了前端
首先,你这样用map和用forEach没什么区别。
其次,对于异步并行操作,用promise.all,不要用单纯的循环。
你这个问题跟map没关系
这样试一下
mongoose 4 操作结果好像是promise
async await 写一个函数new promise你查询到的值,然后用async定义save函数,用await来获取你resolve的值,在通过push生成数组。