2014-06-27 39 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