使用 NodeJS 下载数百万张图片
Download millions of image using NodeJS
我正在开发一个节点应用程序,该应用程序将从地图服务器下载数百万个地图图块(图像),并且图块的网址将由x和y的缩放级别和坐标动态生成,以下是代码:
var tpl_url="http://tile.server.com/{z}/{x}/{y}.png";
var z= 19 ,x_range=[0,10000],y_range=[0,10000],down_dir="download";
function generateUrl(z,x,y){
var obj={x:x,y:y,z:z};
return tpl_url.replace(/'{('w+)'}/g,function(a,key){
return obj[key];
});
}
function generateFilePath(z,x,y){
return path.join(down_dir,z.toString(),x.toString(),y+".png");
}
function download(url,path,callback){
request(url).pipe(fs.createWriteStream(path)).on('error',function(e){
callback && callback(e,url);
}).on('close',function(){
callback && callback(null,url);
});
}
var num = 0;
function onTileLoaded(err,url){
console.log(url+"'t " + (!err?"complete ":"error") + (++num));
}
for(var i=x_range[0];i<=x_range[1];i++){
for(var k=y_range[0];k<=y_range[1];k++){
var x = i,y = k;
var url = generateUrl(z,x,y);
var filePath = generateFilePath(z,x,y);
fs.exists(path.dirname(filePath),function(exists){
if(!exists){
mkdirp(path.dirname(filePath),function(){
download(url,filePath,onTileLoaded);
});
}else{
download(url,filePath,onTileLoaded);
}
});
console.log("iterator:" + i + "," + k);
}
}
现在我遇到了三个问题:
1 变量的值被覆盖
显然,这是行不通的,因为fs.exists
是异步操作,当操作完成后,像url
filePath
这样的变量将被下一个循环覆盖,通常我会像这样通过闭包来关闭这些变量:
for(var i...){
for(var k...){
var x = i,y = k;
var _url = generateUrl(z,x,y);
var _filePath = generateFilePath(z,x,y);
(function(url,filePath){
fs.exists(path.dirname(filePath),function(exists){
if(!exists){
mkdirp(path.dirname(filePath),function(){
download(url,filePath,onTileLoaded);
});
}else{
download(url,filePath,onTileLoaded);
}
});
})(_url,_filePath);
console.log("iterator:" + i + "," + k);
}
}
它有效,但似乎这意味着一旦有异步函数调用,我必须通过自执行的匿名函数进行闭包,我认为这不方便。
所以我想知道你如何解决这种问题?
2 异步操作的执行时间
似乎除非循环完成,否则不会执行异步操作,因此在我的示例中,我必须等待循环10000*10000
次。
我还没有找到解决方案。
3 多线程支持
通常我会创建多个线程来下载Java,C#中的图像,在NodeJS中可以吗?
回答第 3 点,node.js 是单线程的。但是,您可以使用异步代码和回调同时下载多个磁贴 - 您的循环可以继续下一个时间,而前一个磁贴仍在下载,并且在每次下载完成后将被中断以处理回调函数。
相关文章:
- 如何从三张图片中选择一张?其余的必须是看不见的
- 通过onclick事件将一张图片更改为6张图片
- JavaScript indexOf 与数百万个匹配项
- 我用JavaScript FIleReader读了一张图片,但是我无法得到图片的信息
- 为多张图片添加上传前的图片预览
- HTML5画布如何在另一张图片上绘制一张图片
- 如何在渲染由数百万个元素组成的html元素时提高性能
- 完整的背景图片幻灯片jquery,想让幻灯片的最后一张图片可以点击
- 如何在Jquery Mobile中将两张图片居中对齐
- 如何在多张图片上显示fontwo敬畏的图标
- 无法使用formData数组一次上载5张图片
- 如何使用jquery或javascript为两张图片制作动画
- 动态更新数百万个 DOM 元素样式的最快方法
- 如何知道最后一张图片何时到达灯箱2
- 为什么我的 Jquery 轮播不会停留在最后一张图片上
- 数百万个列表映射,100GB数据流畅显示,建议
- 下载多张图片,而无需在Chrome扩展程序中询问
- 连续设置 4 张图片而不是 2 张图片
- jQuery幻灯片,转到上一张图片
- 使用 NodeJS 下载数百万张图片