1

私はNode.jsを使用して単純なアプリに取り組んでおり、有効なURLが与えられたときに次のことを行う必要があります

  1. リモートページのHTMLを取得し、ローカルに保存します。
  2. HTMLを(cheerioを使用して)スパイダーし、すべてのJSおよびCSSファイル参照を記録します。
  3. JS / CSSファイルごとにHTTPリクエストを作成し、ファイル名でサーバーに保存します。
  4. html、css、およびjsファイルを圧縮して、結果のファイルをブラウザーにストリーミングします。

1と2が機能し、#3の前半が機能していますが、ダウンロードの同期性に問題が発生しています。コードの実行速度が速すぎて、CSSファイルとJSファイルのファイル名が生成されていますが、コンテンツが生成されていません。これは私のコードが同期していないためだと思います。問題は、ZIPファイルを生成する前に、ファイルがいくつあるかわからず、すべてのファイルが存在している必要があることです。

これが現在存在する私のアプリの流れです。シンクロニシティに影響を与えないため、ヘルパーメソッドは省略しました。私が何をすべきかについて、誰かが意見を提供できますか?

http.get(fullurl, function(res) {
    res.on('data', function (chunk) {
        var $source = $(''+chunk),
            js = getJS($source, domain),
            css = getCSS($source, domain),
            uniqueName = pw(),
            dir = [baseDir,'jsd-', uniqueName, '/'].join(''),
            jsdir = dir + 'js/',
            cssdir = dir + 'css/',
            html = rewritePaths($source);

        // create tmp directory
        fs.mkdirSync(dir);

        console.log('creating index.html');

        // save index file
        fs.writeFileSync(dir + 'index.html', html);

        // create js directory
        fs.mkdirSync(jsdir);

        // Save JS files
        js.forEach(function(jsfile){
            var filename = jsfile.split('/').reverse()[0];
            request(jsfile).pipe(fs.createWriteStream(jsdir + filename));
            console.log('creating ' + filename);
        });

        // create css directory
        fs.mkdirSync(cssdir);

        // Save CSS files
        css.forEach(function(cssfile){
            var filename = cssfile.split('/').reverse()[0];
            request(cssfile).pipe(fs.createWriteStream(cssdir + filename));
            console.log('creating ' + filename);
        });

        // write zip file to /tmp
        writeZip(dir,uniqueName);

        // https://npmjs.org/package/node-zip
        // http://stuk.github.com/jszip/

    });
}).on('error', function(e) {
    console.log("Got error: " + e.message);
});
4

1 に答える 1

7

リクエストモジュールを介してファイルをダウンロードする方法は非同期です

request(cssfile).pipe(fs.createWriteStream(cssdir + filename));

そのようにダウンロードする代わりに、このようにする必要があります別の関数を作成します

function download (localFile, remotePath, callback) {
var localStream = fs.createWriteStream(localFile);

var out = request({ uri: remotePath });
out.on('response', function (resp) {
    if (resp.statusCode === 200){
        out.pipe(localStream);
        localStream.on('close', function () {
            callback(null, localFile);
        });
    }
    else
        callback(new Error("No file found at given url."),null);
})
};

colanhttps://github.com/caolan/asyncによる非同期モジュールを使用する必要があります

// Save JS files
    async.forEach(js,function(jsfile,cb){
        var filename = jsfile.split('/').reverse()[0];
        download(jsdir + filename,jsfile,function(err,result){
          //handle error here

          console.log('creating ' + filename);
          cb();
        })                        
    },function(err){
     // create css directory
    fs.mkdirSync(cssdir);

    // Save CSS files
    css.forEach(function(cssfile){
        var filename = cssfile.split('/').reverse()[0];
        request(cssfile).pipe(fs.createWriteStream(cssdir + filename));
        console.log('creating ' + filename);
    });

    // write zip file to /tmp
    writeZip(dir,uniqueName);
    });
于 2013-03-26T08:55:15.120 に答える