node.js中的同步获取url?

node.js中的同步获取url?,node.js,Node.js,有没有办法从指定的url同步获取页面源? 问题是我有一个很长的URL列表(比如1000个)要获取和解析,在回调中循环执行这项操作非常痛苦,因为它同时启动所有的fetchUrl函数,并根据回调中的代码解析它 我更希望能够: 获取url1 解析url1源 将解析结果保存到硬盘 获取url2 解析url2源 将解析结果保存到硬盘 。。对所有列表重复此操作 目前,我使用fetch包获取url源,并使用cheerio进行解析。作为web服务器,节点的体系结构和响应能力取决于它没有执行同步(例如阻塞)网络操

有没有办法从指定的url同步获取页面源? 问题是我有一个很长的URL列表(比如1000个)要获取和解析,在回调中循环执行这项操作非常痛苦,因为它同时启动所有的fetchUrl函数,并根据回调中的代码解析它

我更希望能够:

  • 获取url1
  • 解析url1源
  • 将解析结果保存到硬盘
  • 获取url2
  • 解析url2源
  • 将解析结果保存到硬盘
  • 。。对所有列表重复此操作

  • 目前,我使用fetch包获取url源,并使用cheerio进行解析。

    作为web服务器,节点的体系结构和响应能力取决于它没有执行同步(例如阻塞)网络操作。如果您打算在node.js中开发,我建议您学习如何管理异步操作

    以下是用于运行序列化异步操作的设计模式:

    function processURLs(arrayOfURLs) {
        var i = 0;
        function next() {
            if (i < arrayOfURLs.length) {
                yourAsyncOperation(arrayOfURLS[i], function(result) {
                    // this callback code runs when async operation is done
                    // process result here
    
                    // increment progress counter
                    ++i;
                    // do the next one
                    next();
                });
            }
        }
    
        next();
    }
    
    函数处理URL(arrayOfURLs){
    var i=0;
    函数next(){
    if(i
    为了获得更好的端到端性能,您实际上可能希望让N个异步操作同时进行,而不是真正地序列化它们


    您还可以为node.js使用Promissions或几个异步管理库中的任意一个。

    作为web服务器,node的体系结构和响应取决于它不执行同步(例如阻塞)网络操作。如果您打算在node.js中开发,我建议您学习如何管理异步操作

    以下是用于运行序列化异步操作的设计模式:

    function processURLs(arrayOfURLs) {
        var i = 0;
        function next() {
            if (i < arrayOfURLs.length) {
                yourAsyncOperation(arrayOfURLS[i], function(result) {
                    // this callback code runs when async operation is done
                    // process result here
    
                    // increment progress counter
                    ++i;
                    // do the next one
                    next();
                });
            }
        }
    
        next();
    }
    
    函数处理URL(arrayOfURLs){
    var i=0;
    函数next(){
    if(i
    为了获得更好的端到端性能,您实际上可能希望让N个异步操作同时进行,而不是真正地序列化它们


    您还可以为node.js使用Promissions或几个异步管理库中的任意一个。

    使用
    async.queue
    request
    cheerio
    以下是使用
    async.queue解决问题的基本方法

    var Concurrency = 100; // how many urls to process at parallel
    
    var mainQ =async.queue(function(url,callback){
     request(url,function(err,res,body){
       // do something with cheerio.
       // save to disk..
       console.log('%s - completed!',url);
       callback(); // end task
     });
    },Concurrency);
    
    mainQ.push(/* big array of 1000 urls */);
    
    mainQ.drain=function(){
     console.log('Finished processing..');
    };
    

    使用
    async.queue
    request
    cheerio
    以下是使用
    async.queue
    解决问题的基本方法

    var Concurrency = 100; // how many urls to process at parallel
    
    var mainQ =async.queue(function(url,callback){
     request(url,function(err,res,body){
       // do something with cheerio.
       // save to disk..
       console.log('%s - completed!',url);
       callback(); // end task
     });
    },Concurrency);
    
    mainQ.push(/* big array of 1000 urls */);
    
    mainQ.drain=function(){
     console.log('Finished processing..');
    };
    

    同步I/O和节点不混合。如果您真的想进行此同步,那么使用Node将不会获得任何好处—这甚至不可能实现。你可以用Ruby来代替

    其他答案是在生产服务器上执行此操作的正确方法。您应该将请求提交到某种可以限制并发性的队列中,这样您就不会试图一次完成1000个连接。我喜欢这个

    如果这不是用于生产,并且可以使用不稳定的节点版本,则可以获得同步样式语法,该语法使用生成器通过“<代码>收益率<代码> >关键字:

    在函数的中间停止执行。
    var co = require('co'),
        request = require('co-request'),
        cheerio = require('cheerio');
    
    var urls = [];
    for (var i = 0; i < 10; i++)
      urls.push('http://en.wikipedia.org/wiki/Special:Random');
    
    co(function * () {
      for (var i = 0; i < urls.length; i++) {
        var res = yield request(urls[i]);
        console.log(cheerio.load(res.body)('#firstHeading').text());
      }
    })();
    
    或使用:


    同步I/O和节点不混合。如果您真的想进行此同步,那么使用Node将不会获得任何好处—这甚至不可能实现。你可以用Ruby来代替

    其他答案是在生产服务器上执行此操作的正确方法。您应该将请求提交到某种可以限制并发性的队列中,这样您就不会试图一次完成1000个连接。我喜欢这个

    如果这不是用于生产,并且可以使用不稳定的节点版本,则可以获得同步样式语法,该语法使用生成器通过“<代码>收益率<代码> >关键字:

    在函数的中间停止执行。
    var co = require('co'),
        request = require('co-request'),
        cheerio = require('cheerio');
    
    var urls = [];
    for (var i = 0; i < 10; i++)
      urls.push('http://en.wikipedia.org/wiki/Special:Random');
    
    co(function * () {
      for (var i = 0; i < urls.length; i++) {
        var res = yield request(urls[i]);
        console.log(cheerio.load(res.body)('#firstHeading').text());
      }
    })();
    
    或使用:


    这次响应性不是问题。我知道我正在打破设计模式,但对于这项任务,我宁愿同步完成,至少在我的脑海中是这样,但似乎有一些适合我的案例的模式我没有意识到。@Quest-那么你可能使用了错误的工具。这次响应性不是问题。我知道我正在打破设计模式,但对于这项任务,我宁愿同步进行,至少在我看来是这样,但似乎有一些适合我的案例的模式我并不知道。@Quest-那么你可能使用了错误的工具。这不会并行发出100个请求,它受到http客户端的限制-只是想澄清一下。这不会并行发出100个请求,它受到http客户端的限制-只是想澄清一下。