Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Node.js同步下载N个远程文件_Javascript_Node.js_Asynchronous_Express_Synchronous - Fatal编程技术网

Javascript 使用Node.js同步下载N个远程文件

Javascript 使用Node.js同步下载N个远程文件,javascript,node.js,asynchronous,express,synchronous,Javascript,Node.js,Asynchronous,Express,Synchronous,我正在使用Node.js开发一个简单的应用程序,当给定一个有效的URL时,它需要执行以下操作 检索远程页面的HTML,将其保存在本地 爬行HTML(使用cheerio)并记录所有JS和CSS文件引用 对每个JS/CSS文件发出HTTP请求,并按文件名将其保存到服务器 压缩html、css和js文件,并将生成的文件流式传输到浏览器 我已经有了1和2,还有#3的前半部分,但我遇到了下载的同步性问题。我的代码运行得太快,为CSS和JS文件生成文件名,但没有任何内容。我猜这是因为我的代码不同步。问题是,

我正在使用Node.js开发一个简单的应用程序,当给定一个有效的URL时,它需要执行以下操作

  • 检索远程页面的HTML,将其保存在本地
  • 爬行HTML(使用cheerio)并记录所有JS和CSS文件引用
  • 对每个JS/CSS文件发出HTTP请求,并按文件名将其保存到服务器
  • 压缩html、css和js文件,并将生成的文件流式传输到浏览器
  • 我已经有了1和2,还有#3的前半部分,但我遇到了下载的同步性问题。我的代码运行得太快,为CSS和JS文件生成文件名,但没有任何内容。我猜这是因为我的代码不同步。问题是,我事先不知道可能有多少个文件,而且在生成ZIP文件之前,所有文件都必须存在

    以下是我的应用程序当前的流程。我省略了helper方法,因为它们不影响同步性。你们中有谁能就我应该做什么提供意见吗

    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);
    });
    

    通过请求模块下载文件的方式是异步的

    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);
    })
    };
    
    您需要使用colan提供的异步模块


    通过请求模块下载文件的方式是异步的

    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);
    })
    };
    
    您需要使用colan提供的异步模块


    a) 我不认为有一种方法可以在节点b中执行同步http请求)同步执行所有这些操作将是非常糟糕的idea@DeadAlready:+1对于坏主意,尽管已经存在死锁,但要求必须下载index.html中引用的所有CSS/JS文件,以便对其进行压缩。当所有文件都必须存在时,同步还是异步执行都没有区别。a)我不认为有办法在节点中执行同步http请求b)同步执行所有这些操作将是非常糟糕的idea@DeadAlready:+1代表坏主意,虽然已经有人死了,要求是必须下载index.html中引用的所有CSS/JS文件,以便对其进行压缩。无论是同步还是异步执行,在继续操作之前,所有文件都必须存在时没有区别。对于css文件,您需要像我对javascript文件一样执行操作感谢您的帮助@khurrum。对于css文件,您需要像我对javascript文件一样执行操作感谢您的帮助@khurrum。