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 在nodeJS中创建异步while循环_Javascript_Node.js_Asynchronous - Fatal编程技术网

Javascript 在nodeJS中创建异步while循环

Javascript 在nodeJS中创建异步while循环,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,在堆栈中有几个类似的问题,但我不能得到任何适合我的答案,我对Node和异步编程的概念是完全陌生的,所以请耐心听我说 我正在构建一个目前有4步流程的刮板: 我给它一个链接集合 它转到每个链接,在页面上找到所有相关的img src 它找到“下一页”链接,获取其href,从所述href检索dom,并重复步骤2 所有这些imgsrc都被放入一个数组中并返回 这是密码getLinks可以异步调用,但其中的while循环当前无法: function scrape(url, oncomplete) {

在堆栈中有几个类似的问题,但我不能得到任何适合我的答案,我对Node和异步编程的概念是完全陌生的,所以请耐心听我说

我正在构建一个目前有4步流程的刮板:

  • 我给它一个链接集合
  • 它转到每个链接,在页面上找到所有相关的
    img src
  • 它找到“下一页”链接,获取其
    href
    ,从所述
    href
    检索dom,并重复步骤2
  • 所有这些
    imgsrc
    都被放入一个数组中并返回
  • 这是密码
    getLinks
    可以异步调用,但其中的
    while
    循环当前无法:

    function scrape(url, oncomplete) {
        console.log("Scrape Function: " + url);
        request(url, function(err, resp, body) {
            if (err) {
                console.log(UHOH);
                throw err;
            }
            var html = cheerio.load(body);
            oncomplete(html);
        }
        );
    }
    function getLinks(url, prodURL, baseURL, next_select) {
        var urls = [];
        while(url) {
            console.log("GetLinks Indexing: " + url);
            var html = scrape(url, function(data) {
                $ = data;
                $(prodURL).each(function() {
                    var theHref = $(this).attr('href');
                    urls.push(baseURL + theHref);
                }
                );
                next = $(next_select).first().attr('href');
                url  = next ? baseurl + next : null;
            }
            );
        }
        console.log(urls);
        return urls;
    }
    
    目前,这进入了一个无限循环,没有任何刮擦。如果我把
    url=next?baseurl+next:空在回调之外,我得到一个
    “next”未定义的错误


    关于如何重新处理此问题以使其对节点友好有何想法?从这个问题的本质来看,它似乎需要阻塞,不是吗?

    这是一种常见的模式,您希望执行循环,但使用带有回调的异步函数。由于不能等待异步函数,因此不能简单地使用while循环

    一种解决方案是使用“堆栈”(或数组)。用您要处理的初始元素填充此字段。当您发现更多要处理的元素时,请将它们添加到此堆栈。并递归调用函数递增要处理的索引,直到索引超过数组的长度

    e、 g

    函数do\u scrape(堆栈、此url、回调){
    //从该url处的网页获取url列表
    ...
    stack.push(new_url);//向数组添加新元素
    ...
    ...
    callback();//进程回调
    }
    函数进程堆栈(URL的堆栈,idx){
    var this_url=stack_of_url[idx];
    刮擦(
    一堆URL,
    这个网址,,
    函数(){
    if(idx+1

    注意,有很多方法可以实现这一点。为了提高效率,您可以从堆栈中删除已处理的元素。您还可以选择是从头到尾处理堆栈,还是从头到尾处理堆栈,等等。最后请注意,如果在
    do_scrape
    函数中不调用异步函数,那么将有一个很紧的回调循环,node.js将中止,抱怨堆栈太大。

    将while循环重写为递归函数。然后,您将很容易识别如何通过传递回调来实现异步。@Bergi啊,原来我只需要知道名称,我就可以自己解决它了。对于任何一个偶然发现这一点的人来说:这是一个很好的资源
    function do_scrape( stack, this_url, callback ) {
        // get list of URLs from webpage at this_url
        ...
        stack.push( new_url ); // adding new element to array
        ...
        ...
        callback(); // process callback
    }
    
    function process_stack( stack_of_urls, idx ) {
        var this_url = stack_of_urls[idx];
    
        do_scrape(
            stack_of_urls,
            this_url,           
            function () {
                if ( idx + 1 < stack_of_urls.length ) {
                    process_stack( stack_of_urls, (idx + 1) );
                } else {
                    process.exit( 0 );
                }
            }
        );
    }
    
    var stack_of_urls = [ "http://www.yahoo.com/" ];
    process_stack( stack_of_urls, 0 ); // start from index zero