2014-06-27 30 views
0

我已经写了一些JavaScript,以便在核心使用wget从外部网站成功下载数百个文件。
下载所有的文件后,我想与他们做一些事情。问题是,这些文件的大小不一样。所以,最后形成的wget不一定是最后下载的文件,这意味着我无法确定最后一个文件何时完成。
概念:在外部函数中创建一个计数器

但是,我知道总共有多少个文件以及与每个wget关联的编号。

我有3个js文件,[parseproducts.js] ==> [createurl.js] ==> [downloadurl.js]

利用这些信息,我怎么能知道当所有的文件都被下载?

我试图在另一个文件中创建一个“ticker”函数,但函数在每个实例上重置,所以它根本不起作用!

编辑:添加代码最初没有这样做,因为我没有想到人们会想要穿过它!我是新手编程/ JavaScript /节点。请让我知道,如果有什么东西,我可以做的更好(我相信大多数的可能是更有效!)

parseproducts.js

var fs = require('fs'); 
var iset = require('./ticker.js'); 
var createurl = require('./createurl.js'); 
var array = []; 

filename = 'productlist.txt'; 
fs.readFile(filename, 'utf8', function(err, data) { 
    if (err) throw err; 
    content = data; 
    parseFile(); 

}); 

function parseFile() { 
    var stringarray = String(content).split(";"); 
    for (var index = 0; index < stringarray.length; ++index) { 

    createurl(stringarray[index],index,stringarray.length); 
    console.log(index+'/'+stringarray.length+' sent.'); 
    if (index === 0) { 
     iset(true,stringarray.length); 
    } else { 
     iset (false,stringarray.length); 
    } 

    }; 
}; 

createurl.js

function create(partnumber,iteration,total) { 

     var JSdownloadURL = require('./downloadurl.js'); 

     JSdownloadURL(createurl(partnumber),partnumber,iteration,total); 

     function createurl(partnumber) { 
      var URL = ('"https://data.icecat.biz/xml_s3/xml_server3.cgi?prod_id='+partnumber+';vendor=hp;lang=en;output=productxml"'); 
      return URL; 
     }; 
    }; 

module.exports = create; 

downloadurl.js

function downloadurl(URL,partnumber,iteration,total) { 
    // Dependencies 
    var fs = require('fs'); 
    var url = require('url'); 
    var http = require('http'); 
    var exec = require('child_process').exec; 
    var spawn = require('child_process').spawn; 
    var checkfiles = require('./checkfiles.js'); 

    // App variables 
    var file_url = URL; 
    var DOWNLOAD_DIR = './downloads/'; 

    // We will be downloading the files to a directory, so make sure it's there 
    var mkdir = 'mkdir -p ' + DOWNLOAD_DIR; 
    var child = exec(mkdir, function(err, stdout, stderr) { 
     if (err) throw err; 
     else download_file_wget(file_url); 
    }); 

    // Function to download file using wget 
    var download_file_wget = function(file_url) { 


     // compose the wget command 
     var wget = 'wget --http-user="MyAccount" --http-password="MyPassword" -P ' + DOWNLOAD_DIR + ' ' + file_url; 
     // excute wget using child_process' exec function 

     var child = exec(wget, function(err, stdout, stderr) { 
     if (err) throw err; 
     else console.log(iteration+'/'+total+' downloaded.  '+partnumber + ' downloaded to ' + DOWNLOAD_DIR); 



     }); 
    }; 
}; 

module.exports = downloadurl; 

失败的尝试个ticker.js

function iset(bol,total) { 
    if (bol === true) { 
     var i = 0; 
    } else { 
     var i = 1; 
    }; 
    counter(i, total); 
} 



function counter(i,total) { 
    var n = n + i; 
    if (n === (total - 1)) { 
     var checkfiles = require('./checkfiles.js'); 
     checkfiles(total); 
    } else { 
    console.log('nothing done'); 
    }; 
} 

module.exports = iset;  

更新在回答回答

这是我的代码看起来像现在。但是,我得到的错误

child_process.js:945 throw errnoException(process._errno, 'spawn'); ^ Error: spawn EMFILE

// Dependencies 
var fs = require('fs'); 
var url = require('url'); 
var http = require('http'); 
var exec = require('child_process').exec; 
var spawn = require('child_process').spawn; 
var checkfiles = require('./checkfiles.js'); 




function downloadurl(URL,partnumber,iteration,total,clb) { 
    // App variables 
    var file_url = URL; 
    var DOWNLOAD_DIR = './downloads/'; 

    // We will be downloading the files to a directory, so make sure it's there 
    var mkdir = 'mkdir -p ' + DOWNLOAD_DIR; 
    var child = exec(mkdir, function(err, stdout, stderr) { 
     if (err) throw err; 
     else download_file_wget(file_url); 
    }); 


    var child = exec(mkdir, function(err, stdout, stderr) { 
     if (err) { 
      clb(err); 
     } else { 
      var wget = 'wget --http-user="amadman114" --http-password="Chip10" -P ' + DOWNLOAD_DIR + ' ' + file_url; 

      // excute wget using child_process' exec function 
      var child = exec(wget, function(err, stdout, stderr) { 
       if (err) { 
        clb(err); 
       } else { 
        console.log(iteration+'/'+total+' downloaded.  '+partnumber + ' downloaded to ' + DOWNLOAD_DIR); 
        clb(null); // <-- you can pass more args here if you want, like result 
        // as a general convention callbacks take a form of 
        // callback(err, res1, res2, ...) 
       } 
      }); 
     } 
    }); 
}; 

function clb() { 
    var LIMIT = 100, 
     errs = []; 
    for (var i = 0; i < LIMIT; i++) { 
     downloadurl(URL,partnumber,iternation,total, function(err) { 
     if (err) { 
      errs.push(err); 
     } 
     LIMIT--; 
     if (!LIMIT) { 
      finalize(errs); 
     } 
     }); 
    } 
} 

function finalize(errs) { 
    // you can now check for err 
    //or do whatever stuff to finalize the code 
} 
module.exports = downloadurl; 
+0

如果您在函数外部声明变量,则不应每次都重置。 – Barmar

+0

发表一些代码 – Gabs00

+1

你需要展示一些代码,我们不能告诉你做错了什么,并建议如何解决它而不看它。 – Barmar

回答

1

行,所以你有这个功能downloadurl。你需要做的是再传一个参数:回调。请移除功能之外的要求,除非必要,不要在功能中定义功能:

var fs = require('fs'); 
// other dependencies and constants 

function downloadurl(URL,partnumber,iteration,total, clb) { // <-- new arg 
    // some code 
    var child = exec(mkdir, function(err, stdout, stderr) { 
     if (err) { 
      clb(err); 
     } else { 
      var wget = 'wget --http-user="MyAccount" --http-password="MyPassword" -P ' + DOWNLOAD_DIR + ' ' + file_url; 

      // excute wget using child_process' exec function 
      var child = exec(wget, function(err, stdout, stderr) { 
       if (err) { 
        clb(err); 
       } else { 
        console.log(iteration+'/'+total+' downloaded.  '+partnumber + ' downloaded to ' + DOWNLOAD_DIR); 
        clb(null); // <-- you can pass more args here if you want, like result 
        // as a general convention callbacks take a form of 
        // callback(err, res1, res2, ...) 
       } 
      }); 
     } 
    }); 
}; 

这看起来更好,不是吗?现在,当您多次致电此功能时,请执行以下操作:

var LIMIT = 100, 
    errs = []; 
for (var i = 0; i < LIMIT; i++) { 
    downloadurl(..., function(err) { 
     if (err) { 
      errs.push(err); 
     } 
     LIMIT--; 
     if (!LIMIT) { 
      finalize(errs); 
     } 
    }); 
} 

function finalize(errs) { 
    // you can now check for err 
    //or do whatever stuff to finalize the code 
} 

这是一个普遍的想法。你必须调整它以满足你的需求(尤其是你必须修改中间函数来接受回调)。当然,有些库会为您处理大部分这类问题,如kriskowal's QQ.all)或caolan's asyncasync.parallel)。

+0

谢谢你的回答和建议。对于如何使用“限制”代码,我只是有点困惑。我已经更新了我的问题 – Dan

+0

@Dan它意味着你已经打开了太多的文件描述符。平行地发布太多的工作。要么增加'ulimit'(谷歌它)或实现某种类型的队列,这将不允许你发出更多的然后说20个并行请求。 – freakish

+0

啊,好的。但是,我自己实现代码的方式是正确的吗? – Dan

0

不知道如果我理解正确的问题,因为我看不到代码。我一直在创建一个下载引擎。我曾经让背景AJAX调用下载文件。每次成功下载或'onComplete'事件后,我都会增加一个变量以跟踪下载的文件。 Provdided用户不会刷新页面,直到所有下载完成。否则,下载计数器也可以保存在LocalStorage中。

+0

从他使用wget的事实来看,我认为他在谈论服务器端JavaScript。除此之外,使用'onComplete'处理程序的想法是绝对正确的。 – freakish