javascript - Conceptual: Create a counter in an external function -
i've written javascript download hundreds of files external site, using wget @ core.
after downloading of files, stuff them. issue is, files aren't of equal size. so, last wget formed isn't last file downloaded, meaning can't tell when last file has completed.
i do, however, know how many files there in total, , number associated each wget.
i have 3 js files, [parseproducts.js] ==> [createurl.js] ==> [downloadurl.js]
using information, how can tell when of files have been downloaded?
tried creating "ticker" function in file function resets on each instance, doesn't work @ all!
edit: code added didn't because didn't think people want trawl through it! i'm new programming/javascript/node. please let me know if there's better (i'm sure of more efficient!)
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(";"); (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/'; // downloading files directory, 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 download file using wget var download_file_wget = function(file_url) { // compose 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 ' + download_dir); }); }; }; module.exports = downloadurl;
failed attempt ticker.js
function iset(bol,total) { if (bol === true) { var = 0; } else { var = 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;
update in response answer
this code looks now. however, error
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/'; // downloading files directory, 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 ' + download_dir); clb(null); // <-- can pass more args here if want, result // general convention callbacks take form of // callback(err, res1, res2, ...) } }); } }); }; function clb() { var limit = 100, errs = []; (var = 0; < limit; i++) { downloadurl(url,partnumber,iternation,total, function(err) { if (err) { errs.push(err); } limit--; if (!limit) { finalize(errs); } }); } } function finalize(errs) { // can check err //or whatever stuff finalize code } module.exports = downloadurl;
ok, have function downloadurl
. need pass 1 more argument it: callback. , please, move requirements outside function , don't define function in function unless necessary:
var fs = require('fs'); // other dependencies , constants function downloadurl(url,partnumber,iteration,total, clb) { // <-- new arg // 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 ' + download_dir); clb(null); // <-- can pass more args here if want, result // general convention callbacks take form of // callback(err, res1, res2, ...) } }); } }); };
this nicer, doesn't it? when call function multiple times do:
var limit = 100, errs = []; (var = 0; < limit; i++) { downloadurl(..., function(err) { if (err) { errs.push(err); } limit--; if (!limit) { finalize(errs); } }); } function finalize(errs) { // can check err //or whatever stuff finalize code }
that's general idea. have tweak needs (in particular have modify intermediate function accept callback well). of course there libraries take care of kriskowal's q (q.all
) or caolan's async (async.parallel
).
Comments
Post a Comment