首页 / 大数据 / 大数据采集中的异步处理问题
大数据采集中的异步处理问题
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了大数据采集中的异步处理问题,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2749字,纯文字阅读大概需要4分钟。
内容图文
这段时间在学习nodejs,用jsdom采集了一些数据,也遇到了一些问题,贴出来征求一下大家的解决方案。
首先说一下目的,有几十万条图片数据,把这些图片抓取到本地文件夹中,采集完成后把成功数据归档为done.json,失败数据归档为undone.json,如下:
1 const IMGS = [ 2 "http://xxx.com/1.jpg", 3 "http://xxx.com/2.jpg", 4 "http://xxx.com/3.jpg", 5 "http://xxx.com/4.jpg", 6 ...//此处省略无数的数据7 ];
采集的心路历程:
方法1 forEach循环直接请求(失败)
1 IMGS.forEach(v=>{ 2 http.get(v, (res)=> { 3//blablabla4 }); 5 });
这种方法一下子就把所有数据都异步的请求出去了,超出了网络链接数,直接就把服务爆掉了。
方法2 采用递归处理完一条自动处理下一条。(成功,但是有问题)
1 const DONE = [], 2 UNDONE = [], 3 FILEDONE = ‘./done.json‘, 4 FILEUNDONE = ‘./undone.json‘; 5 let counter = 0; 6 const writeResult() =>{ 7 fs.writeFile(FILEDONE, JSON.stringify(DONE), "utf8", ()=>console.log(‘done saved!‘)); 8 fs.writeFile(FILEUNDONE , JSON.stringify(UNDONE), "utf8", ()=>console.log(‘undone saved!‘)); 9} 10const saveImage = (data, fn)=> { 11 fs.writeFile(counter++ + ‘.jpg‘, data, fn); 12 } 13 const downloadImage = (i)=> { 14if(i >= IMGS.length) { 15 writeResult(); 16return; 17 } 18 http.get(IMGS[i], (res)=> { 19//此处略去了异常处理的内容20 res.setEncoding="binary"; 21 let dt = ‘‘; 22 res.on(‘data‘, (ck)=> dt+=ck;) 23 res.on(‘end‘,()=> { 24 saveImage(dt, ()=> { 25 DONE.push(IMGS[i]); 26 downloadImag(i++); 27 }); 28 }) 2930 }).on(‘error‘,()=>UNDONE.push(IMGS[i])) ; 31} 3233 downloadImage(0);
这种方法的确是能成功抓取到了数据,但是有一个最大的弊端就是只能一条一条顺序抓取,没办法批量并发一起抓取,这简直就是浪费了nodejs非阻塞机制。
好,变通处理添加循环多处理机制。
方法3 采用添加间隔器的方式进行批量处理。
const DONE = [], UNDONE = [], FILEDONE = ‘./done.json‘, FILEUNDONE = ‘./undone.json‘, STEP = 20; let counter = 0, stepi = 0; const writeResult() =>{ if(stepi < STEP) return; //只有全部都请求完后才真正执行归档功能 fs.writeFile(FILEDONE, JSON.stringify(DONE), "utf8", ()=>console.log(‘done saved!‘)); fs.writeFile(FILEUNDONE , JSON.stringify(UNDONE), "utf8", ()=>console.log(‘undone saved!‘)); } const saveImage = (data, fn)=> { fs.writeFile(counter++ + ‘.jpg‘, data, fn); } const downloadImage = (i)=> { if(i >= IMGS.length) { stepi++; writeResult(); return; } http.get(IMGS[i], (res)=> { //此处略去了异常处理的内容 res.setEncoding="binary"; let dt = ‘‘; res.on(‘data‘, (ck)=> dt+=ck;) res.on(‘end‘,()=> { saveImage(dt, ()=> { DONE.push(IMGS[i]); downloadImag(i + STEP); }); }) }).on(‘error‘,()=>{ downloadImag(i + STEP); UNDONE.push(IMGS[i]) }); } for(let i = 0; i < STEP; i++) { downloadImage(i); }//循环step个请求
方法4. 利用promise对象(暂时还未成功,还在想办法,有想法的同学可以贴出来大家借鉴一下)
let promise_imgs = IMGS.map(v => { new Promise((resolve, reject)=> { setTimeout(()=>{ http.get(v, (res)=> { //blablabla res.on(‘end‘, ()=> saveImage(dt, ()=>resolve()) }) }) }, 0); }); }); Promise.all(promise_imgs).then(writeResult);//这里还是会发生和方法1一样的问题,多回调异步并发造成网络链接数的用尽,
大家有什么好的方法快快贴出来吧!
原文:https://www.cnblogs.com/jingyingggong/p/8460851.html
内容总结
以上是互联网集市为您收集整理的大数据采集中的异步处理问题全部内容,希望文章能够帮你解决大数据采集中的异步处理问题所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。