Boy*_*ang 1 memory-management node.js promise jsdom es6-promise
我有一个脚本来刮掉~1000个网页.我正在使用Promise.all将它们组合在一起,并在所有页面完成后返回:
Promise.all(urls.map(url => scrap(url)))
.then(results => console.log('all done!', results));
Run Code Online (Sandbox Code Playgroud)
这是好的和正确的,除了一件事 - 由于并发请求,机器内存不足.我用jsdom它来进行报废,它会快速占用几GB的内存,考虑到实例化数百个内存,这是可以理解的window.
我有一个想法,但我不喜欢它.也就是说,改变控制流程不使用Promise.all,但链接我的承诺:
let results = {};
urls.reduce((prev, cur) =>
prev
.then(() => scrap(cur))
.then(result => results[cur] = result)
// ^ not so nice.
, Promise.resolve())
.then(() => console.log('all done!', results));
Run Code Online (Sandbox Code Playgroud)
这不如Promise.all ...不符合链接,并且必须存储返回的值以供以后处理.
有什么建议?我应该改进控制流程还是应该改进scrap()中的mem使用,还是有办法让节点限制内存分配?
您正尝试并行运行1000个Web抓取.您需要选择一些远小于1000的数字,并且一次只运行N,这样您在执行此操作时会消耗更少的内存.您仍然可以使用承诺来跟踪它们何时完成.
BluebirdPromise.map()可以通过传递并发值作为选项来为您做到这一点.或者,你可以自己写.
我有一个想法,但我不喜欢它.也就是说,改变控制流程不使用Promise.all,但链接我的承诺:
你想要的是同时在飞行中的N次操作.排序是一种特殊情况,N = 1其中通常比并行执行某些操作要慢得多(可能还有N = 10).
这不如Promise.all ...不符合链接,并且必须存储返回的值以供以后处理.
如果存储的值是您的内存问题的一部分,您可能必须以任何方式将它们存储在内存中.您将不得不分析存储结果使用的内存量.
有什么建议?我应该改进控制流程还是应该改进scrap()中的mem使用,还是有办法让节点限制内存分配?
使用BluebirdPromise.map()或自己写类似的东西.编写一些并行运行N个操作并保持所有结果有序的东西并不是火箭科学,但要做到这一点需要做一些工作.我之前在另一个答案中提出过它,但现在似乎无法找到它.我会继续寻找.
在此处找到我之前的相关答案:向API发出几个请求,每分钟只能处理20个请求
| 归档时间: |
|
| 查看次数: |
1629 次 |
| 最近记录: |