【问题标题】:Async Await not behaving as expected异步等待未按预期运行
【发布时间】:2019-04-09 03:10:39
【问题描述】:

我正在尝试在我的节点服务器中执行一个功能,该功能使用cheerio 抓取网络,问题是由于某种原因我的功能没有按预期运行,

控制器:

class ScraperController {
    static async scrapeDwelling(req, res, next) {
        try {
            const dwelling = await ScraperService.getDwelling(req.params.url);
            console.log(dwelling);
            res.send({dwelling});
        } catch (err) {
            next(err);
        }
    }
}

那么我的服务:

static async getDwelling(url) {
    const dwelling = {};
    await request(`https://www.zonaprop.com.ar/propiedades/${url}`, (err, resp, html) => {
        const $ = cheerio.load(html);
        dwelling.type = $('.price-operation', '#article-container').text();
        dwelling.price = $('.price-items', '#article-container').text();
        dwelling.description = $('.section-description', '#article-container').text();
        dwelling.title = $('.title-type-sup > b').text();
        dwelling.location = $('.title-location > b').text();
        const coordinatesHelper = ($('.static-map', '#article-map').attr('src'));
        const coordinates = coordinatesHelper.substring(
            coordinatesHelper.lastIndexOf('markers=') + 8,
            coordinatesHelper.lastIndexOf('&channel')
        );
        dwelling.coordinates = coordinates;
        console.log($('#tab-foto-flickity').find('img').length);
        return dwelling;
    });
    return dwelling;
}

当您看到控制台日志时,由于某种原因,该函数首先返回,然后执行代码。我在控制台中得到了这个:

{}

GET /public-api/scraper/42998731.html 200 6.559 毫秒 - 15

36

【问题讨论】:

    标签: node.js express ecmascript-6


    【解决方案1】:

    request 节点模块不返回承诺,它使用回调函数。您可以像这样手动将您的请求包装在 Promise 中:

    static getDwelling(url) {
        return new Promise((resolve, reject) => {
            request(`https://www.zonaprop.com.ar/propiedades/${url}`, (err, resp, html) => {
                if(err) {
                    return reject(err);
                }
                resolve(html);
            });
        }).then((html) => {
            const $ = cheerio.load(html);
            const dwelling = {};
            dwelling.type = $('.price-operation', '#article-container').text();
            dwelling.price = $('.price-items', '#article-container').text();
            dwelling.description = $('.section-description', '#article-container').text();
            dwelling.title = $('.title-type-sup > b').text();
            dwelling.location = $('.title-location > b').text();
            const coordinatesHelper = ($('.static-map', '#article-map').attr('src'));
            const coordinates = coordinatesHelper.substring(
                coordinatesHelper.lastIndexOf('markers=') + 8,
                coordinatesHelper.lastIndexOf('&channel')
            );
            dwelling.coordinates = coordinates;
            console.log($('#tab-foto-flickity').find('img').length);
            return dwelling;
        });
    }
    

    或者您可以使用像 request-promise-native 这样的库。

    【讨论】:

    • 最好立即执行resolve([resp, html]);,然后使用cheerio.load(html); 执行.then(([resp, html]) => { 等,这样如果其他任何逻辑抛出,promise 将拒绝正确地而不是抛出未捕获的异常。通常,您希望new Promise 块的大小尽可能小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 2019-04-19
    • 2020-03-04
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多