我正在研究節點應用程序,它將從地圖服務器下載數百萬個地圖圖塊(圖像),並且圖塊的網址將由縮放級別和x和y座標動態生成,這裏是代碼:使用NodeJS下載數百萬圖像
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
如ynchronous操作,當操作完成後,像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?
使用異步庫https://github.com/caolan/async – siddick
凡是需要下載圖像的數以百萬計的聲音緩慢,可能是不必要的,如果一個指數可以建立在現有的圖像,也許喜歡那種刮即某人可能會注意並關閉。 – Paul
那麼對於這種工具有什麼建議? – hguser