在循环中使用时异步功能被卡住(scraperjs)

时间:2017-10-28 02:30:29

标签: javascript asynchronous web-scraping

我尝试使用异步的ruipgil / scraperjs函数制作一个刮刀。但是当我把它放在一个循环中时,它就会卡住并且不会起作用。我是Node的新手和异步编程的想法所以请耐心等待。

所以,我有这段代码:

let scraperjs = require('scraperjs');

// scraper function
function scrape(pageURI, callback) {
    console.log('checkpoint 2'); // checkpoint
    scraperjs.StaticScraper.create(pageURI).scrape(function($) {
        console.log('checkpoint 3'); // checkpoint
        return $("div").map(function() {
            return $(this).text();
        }).get();
    }).then(function(sometext) {
        callback(sometext);
    });
}

// loop function
function testloop() {
    let finished = false;
    let processed = false;

    while (!finished) {
        if (!processed) {
            console.log('checkpoint 1'); // checkpoint
            scrape('https://www.google.com/', (sometext) => {
                console.log('checkpoint 4', sometext); // checkpoint
                finished = true;
            });
            processed = true;
        }
    }
}

// non loop function
function testnonloop() {
    console.log('checkpoint 1'); // checkpoint
    scrape('https://www.google.com/', (sometext) => {
        console.log('checkpoint 4', sometext); // checkpoint
    });
}

我试图调度两个期望完整的4个检查点输出的函数。但奇怪的是,带有循环的那个在检查点2中被卡住而且从未进展过。 [我也尝试使用promise而不是回调样式,但仍然是相同的输出。]

我哪里出错?

2 个答案:

答案 0 :(得分:1)

您可以尝试使用递归,这样它就不会卡在那个循环中吗?

// loop function
function testloop() {
    console.log('checkpoint 1'); // checkpoint
    scrape('https://www.google.com/', (sometext) => {
        console.log('checkpoint 4', sometext); // checkpoint
        testLoop();
    });
}

答案 1 :(得分:1)

问题是while循环中的条件永远不会改变,因为回调函数永远不会被执行。

这是因为JavaScript程序在事件循环中执行。 JavaScript引擎有调用堆栈(记录我们在程序中的位置)和回调队列(跟踪要执行的异步回调)。

事件循环监控呼叫堆栈回拨队列。如果调用堆栈为空,它将从回调队列中获取第一个事件,并将其推送到运行它的调用堆栈

在你的情况下,调用堆栈永远不会变空,它总是忙于while循环,因此永远不会执行回调,所以while条件总是{ {1}}。

可能的解决方案是使用true来调用setTimeout,直到第一个回调被调用。使用scrape,您将释放调用堆栈,让异步调用执行。

setTimeout

您可以在此处找到有关事件循环的更深入说明:How JavaScript works: an overview of the engine, the runtime, and the call stack