Javascript 如何在Node.js中同步使用请求?

Javascript 如何在Node.js中同步使用请求?,javascript,node.js,callback,promise,Javascript,Node.js,Callback,Promise,下面是我的基本脚本,用于抓取给定的URL并获取其中的所有链接。 我想在请求功能完成后打印链接\u arr。但是,这里执行了请求回调函数,因此,我得到了一个空数组。如何同步执行此操作?i、 e.按以下顺序 请求URL Cheerio获得所有链接 我们循环遍历所有项,并将它们插入links\u arr数组 打印数组 另外,我知道Node.js用于异步任务,但这是我需要满足的要求。我读到一些像承诺这样的东西可以在这方面帮助我,但是,由于我在Node方面没有高级知识,我不知道如何实现它。如果能帮上点忙,

下面是我的基本脚本,用于抓取给定的URL并获取其中的所有链接。 我想在请求功能完成后打印
链接\u arr
。但是,这里执行了请求回调函数,因此,我得到了一个空数组。如何同步执行此操作?i、 e.按以下顺序

  • 请求URL
  • Cheerio获得所有链接
  • 我们循环遍历所有项,并将它们插入links\u arr数组
  • 打印数组
  • 另外,我知道Node.js用于异步任务,但这是我需要满足的要求。我读到一些像承诺这样的东西可以在这方面帮助我,但是,由于我在Node方面没有高级知识,我不知道如何实现它。如果能帮上点忙,我将不胜感激。 我正在使用该库进行http请求、url解析和html解析

    var request = require('request');
    var cheerio = require('cheerio');
    var url = require('url');
    var all_links = [];
    var processing = [];
    var processed = [];
    var base_url = "https://www.npmjs.com";
    var base_host = "www.npmjs.com";
    
    
    var analyze_href_sync = function(u){
        console.log("Analysing URL "+u);
        url_obj = url.parse(u);
        url_formatted = url.format(url_obj);
        if (!url_obj.host) {
            //Relative URL
            resolved_url = url.resolve(base_url, url_formatted);
            return resolved_url;
        } else if (url_obj.protocol.startsWith("http")){
            if (url_obj.host == base_host) {
                return url_formatted;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    
    var scrape_all_links_sync = function(u){
        console.log("Scraping all links from URL "+u);
        var links_arr = [];
        request(u, function(err, res, body){
            $ = cheerio.load(body);
            links = $('a');
            $(links).each(function(i, link){
                href = $(link).attr('href');
                console.log(href);
                links_arr.push(href);
            });
        });
    
        console.log(links_arr); //Need to print this, after the above request loopo is complete. i.e. After the array is filled.
    }
    
    var store_into_csv_sync = function(u){
    
    }
    
    var insert_into_processing_sync = function(u){
    
    }
    
    var remove_from_processing_sync = function(u){
    
    }
    
    var main = function(u){
        var analyze_url = analyze_href_sync(u);
        if (analyze_url != false) {
            scrape_all_links_sync(analyze_url);
        }
    }
    
    main(base_url);
    
    上述脚本的输出是

    Analysing URL https://www.npmjs.com
    Scraping all links from URL https://www.npmjs.com/
    []
    ...
    *All the other links found*
    

    您需要放置
    console.log(links\u arr)在回调函数中:

    var scrape_all_links_sync = function(u){
    console.log("Scraping all links from URL "+u);
    var links_arr = [];
    request(u, function(err, res, body){
        $ = cheerio.load(body);
        links = $('a');
        $(links).each(function(i, link){
            href = $(link).attr('href');
            console.log(href);
            links_arr.push(href);
        });
        console.log(links_arr); //Need to print this, after the above request loop is complete. i.e. After the array is filled.
      });
    }
    
    所以只要移动1行语句,就可以了

    在JavaScript中,我们有3种处理异步代码的方法:

  • 回调
  • 许诺
  • 基于生成器的

  • 因此,您可以选择使用哪一种,也可以混合使用(例如,取决于您使用的库)。您可以阅读。

    有许多库模拟异步等待任务。几周前我发布了我的(Awync)。你可能想看看,这比我想象的要简单得多。成功了。我将编辑我的答案并添加一些对异步回调的引用。我将非常感谢。谢谢
    $(links).each(function(i, link){
                href = $(link).attr('href');
                console.log(href);
                links_arr.push(href);
         if(i==links.length-1)
            console.log(links_arr);  
            });