在 nodejs 中放置回调的语法和方法

syntax and methods for placing callbacks in nodejs

我在使用 express 库的 nodejs 中有以下 http 端点:

app.get("/api/stocks/lookup/:qry", function(req, res) {
    getJson(lookupSearch(req.params.qry), function(json) {
        var quotes = [];
        und.forEach(json, function(d) {
            getJson(quoteSearch(d.Symbol), function(j) {
                quotes.push(j);
            });
        });
        res.send(quotes);     //how can I make this execute after the .forEach is finished?
    });
});

在这里,getJson 看起来像这样:

var getJson = function(search, cb) {
    http.request(search, function(response) {
        var raw = '';
        response.on('data', function(d) {
            raw += d;
        });
        response.on('end', function() {
            cb(JSON.parse(raw));
        });
        response.on('error', function(err) {
            console.error(err);
        });
    }).end();
};

我明白为什么这行不通了,因为 getJson 中的 http 请求是异步的,因此 res.send(quotes) 几乎会立即发回。那么,如何在 forEach 循环完成后发送 res.send(quotes) 呢?我可以将回调附加到 forEach 函数吗?

综上所述,

  1. forEach循环完成后如何使用res.send(quotes)
  2. 是否可以将回调(例如在 forEach 循环之后执行的回调)附加到对象上?我可以将回调附加到什么?需要明确的是,'callback' 对我来说意味着事件循环将在回调所附加的 function/object 完成执行后调用它。

感谢大家的帮助!

将 getJson 转换为 promise 是个好主意,因为 promise 很适合使用。没有承诺,手动方式是保留未完成请求的计数器:

var outstanding = 0;
json.forEach(function(d) {
    outstanding++;
    getJson(quoteSearch(d.Symbol), function(j) {
        quotes.push(j);
        if (!--outstanding) {
            res.send(quotes);
        }
    });
});

如果您确实采用了承诺的方式,您将 map 超过 json,并且 return 请求的承诺;然后您可以在承诺数组上指定 then 。如果您使用 jQuery 而不是您自己的自制解决方案,例如,

var requests = json.map(function(d) {
    return $.getJSON(quoteSearch(d.Symbol), function(j) {
        quotes.push(j);
    });
});
$.when(requests).then(function() {
    res.send(quotes);
});

(未经测试的代码)。