2015-01-06 62 views
0

我正在研究節點應用程序,它將從地圖服務器下載數百萬個地圖圖塊(圖像),並且圖塊的網址將由縮放級別和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操作,當操作完成後,像urlfilePath變量將被下一個循環覆蓋,通常我會關閉關閉這些變量是這樣的:

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?

+0

使用異步庫https://github.com/caolan/async – siddick

+0

凡是需要下載圖像的數以百萬計的聲音緩慢,可能是不必要的,如果一個指數可以建立在現有的圖像,也許喜歡那種刮即某人可能會注意並關閉。 – Paul

+0

那麼對於這種工具有什麼建議? – hguser

回答

0

要回答第3點,node.js是單線程的。但是,您可以使用異步代碼和回調來同時下載多個切片 - 您的循環可以繼續下一次,而以前的切片仍在下載,並且在每次下載完成後將被中斷以處理回調函數。

+0

可以創建其他進程並在這些進程中運行下載命令。請參閱:[node.js過程API](http://nodejs.org/api/process.html) – Paul