javascript - Node.js 中的异步函数

标签 javascript node.js api asynchronous semaphore

我的 Node.js API 中有一个端点,它返回由 Google-Search-scraper 库提供的结果的 JSON 数组。

app.get('/google_image_search', (req, res) => {
    var options = {
        query: 'grenouille',
        age: 'y', // last 24 hours ([hdwmy]\d? as in google URL)
        limit: 10,
        params: {} // params will be copied as-is in the search URL query string
    };

    var results = [];
    scraper.search(options, function(err, url, meta) {
        sem.take(function() { 
            if(err) throw err;

            var result = {
                title: meta.title,
                meta: meta.meta,
                description: meta.desc
            }
            results.push(result);
            sem.leave();
        });
    })

    console.log(results);

    res.json({
        results
    });
})

我需要 console.log(results) 和 res.json({ results }) 在 scraper.search 函数完成后发生。它目前总是返回一个空数组。

传递给 scraper.search() 函数的函数会为每个结果调用。因此,如果函数运行 10 次有 10 个结果,这就是为什么我要等到数组已满才发送响应。

我曾尝试在不同的地方使用信号量和互斥锁,但没有成功。任何建议表示赞赏。


这已通过使用 LIMIT 变量来检查我的结果数组来解决。在下面标记为正确的答案中概述。

感谢大家的投入。


最佳答案

res.send 放在回调之外将导致类似于 this problem 的竞争条件. google-search-scraper 库的一个缺点是它不是为收集结果而设计的。

这应该是固定的:

var LIMIT = 10;
var options = { limit: LIMIT, ... };

var results = [];
var errs = [];
var resultsCount = 0;

function resultsHandler() {
    if (errs.length) {
       // handle error
    } else
       res.json({ results });
}

scraper.search(options, function resultHandler(err, url, meta) {
    if (err)
        errs.push(err);
    else {
        var result = {
            title: meta.title,
            meta: meta.meta,
            description: meta.desc
        };

        results.push(result);
    });

    resultsCount++;

    if (resultsCount === LIMIT)
       resultsHandler();
});

如果 search 有可能在某些情况下不调用回调,这将不起作用。

关于javascript - Node.js 中的异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54618781/

相关文章:

javascript - 如何使用 pygtk+ WebKit 自动填充输入字段

javascript - 我怎样才能访问倒数第二个 child ?

node.js - 未找到命令 : node-inspector

node.js - 如何使用 ExpressJS 在同一个响应对象上多次渲染?

api - Foursquare 签到 API

javascript - 相同域策略 jQuery

javascript - 如何在 contenteditable div 中获取已删除的元素?

javascript - PhantomJs:Spawn 未打开任何应用程序

java - Spring API : the program is not finding the pat into the controller

objective-c - Objective-C 的 Web API 介绍?