2015-01-06 61 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