为什么用 co + map 的时候不会释放内存

2017-02-21 16:39:11 +08:00
 ufo22940268

snippet1

co(function* () {
  yield largeArray.map(function* (e) {
     const k = yield db.col.findById(e).exec()
     do something with k
  })
})

snippet2

Promise.map(largeArray, (e) => {
   return db.col.findById(e).exec()
   	.then(k => {
    	do something with k
    })
})

这上面用的库有

完成的操作就是遍历 id array ,然后把数据从 mongodb 从取出来操作下。但是经过测试,发现 snippet1 会导致内存溢出,但是 snippet2 不会。感觉好像 snippet1 在function* (){}生命周期结束之后,不会马上释放内存。没有研读过tj/co的源码,求大神指点

2049 次点击
所在节点    Node.js
9 条回复
zbinlin
2017-02-21 17:33:02 +08:00
把 snippet1 里的 generator 也换成 promise 试试:

co(function* () {
  yield largeArray.map(function (e) {
     return db.col.findById(e).exec()
        .then(k => {
            do something with k
        })
  })
})


PS: 话说你的 largeArray 究竟有多大呀?
binux
2017-02-21 17:43:03 +08:00
你的 snippet1 真的 work 吗?你只给 yield largeArray.map 包了 co , largeArray.map 也支持 generator ?
zbinlin
2017-02-21 17:46:05 +08:00
@binux 应该是 co 支持 generator array
ufo22940268
2017-02-21 17:50:46 +08:00
@zbinlin largeArray 也不会很大,就几万,但是中间查询的结果数据量比较大
cheetah
2017-02-21 18:18:25 +08:00
原因是,在 snippet1 中, largeArray.map 并不会等所有 callback 执行完后才返回,也就是说 Array.prototype.map 并没有 『如果 callback 返回的是个 Promose 则等待』的功能,这种情况就应该用 Promise.map
binux
2017-02-21 18:56:28 +08:00
@zbinlin 确实,不过 https://www.npmjs.com/package/co#yieldables
array (parallel execution) 这应该是问题所在
zbinlin
2017-02-21 19:01:59 +08:00
@binux 如果 snippet2 Promise 用的是 bluebird ,面里的 Promise.map 也是并行执行的: http://bluebirdjs.com/docs/api/promise.map.html
binux
2017-02-21 19:06:03 +08:00
@zbinlin #7 那就是 snippet1 的 `do something with k` return k 了, snippet2 没有
cheetah
2017-02-21 19:09:20 +08:00
对 co 不太熟,我把它转成 async/await 的形式是这样没错吧?

await largeArray.map(async (e) => {
const k = await db.col.findById(e).exec()
do something with k
})

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/342095

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX