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

syntax and methods for placing callbacks in nodejs

本文关键字:语法 方法 回调 NodeJS      更新时间:2023-09-26

我在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. 是否可以将回调
  3. (例如在forEach循环后执行的回调)附加到对象上?我可以将回调附加到什么?需要明确的是,对我来说,"回调"的想法意味着事件循环将在回调附加到的函数/对象完成执行后调用它。

感谢所有的帮助!

将 getJson 转换为承诺将是一个好主意,因为承诺很好用。如果没有承诺,手动方法是保留未完成请求的计数器:

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

如果你确实按照承诺的方式走,你会对json进行map,并返回请求的承诺;然后你可以在承诺数组上指定一个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);
});

(未经测试的代码)。