【问题标题】:Node.js and Express: How to return response after asynchronous operationNode.js 和 Express:异步操作后如何返回响应
【发布时间】:2016-08-18 16:39:57
【问题描述】:

我是 Node.js 的新手,所以我仍然在关注异步函数和回调。我现在的难题是如何在异步操作中从文件中读取数据后返回响应。

我的理解是发送响应是这样的(这对我有用):

app.get('/search', function (req, res) {
    res.send("request received");
});

但是,现在我想读取一个文件,对数据执行一些操作,然后在响应中返回结果。如果我想对数据执行的操作很简单,我可以这样做——内联执行它们,并保持对 res 对象的访问,因为它仍在范围内。

app.get('/search', function (req, res) {
    fs.readFile("data.txt", function(err, data) {
        result = process(data.toString());
        res.send(result);
    });
});

但是,我需要执行的文件操作又长又复杂,以至于我将它们分离到单独的文件中的自己的函数中。结果,我的代码看起来更像这样:

 app.get('/search', function (req, res) {
    searcher.do_search(res.query);
    // ??? Now what ???
});

我需要致电res.send 以发送结果。但是,我不能直接在上面的函数中调用它,因为do_search是异步完成的。而且我不能在对do_search 的回调中调用它,因为res 对象不在该范围内。

有人可以帮我理解在 Node.js 中处理这个问题的正确方法吗?

【问题讨论】:

  • 我会说,要么将res 对象作为参数传递给函数,要么将其作为参数传递给函数,然后在工作完成时调用它(即创建您自己的回调)。后者可能会更好,因为它不会将您的代码耦合到 Express 的 API。

标签: javascript node.js express asynchronous


【解决方案1】:

要访问不同函数中的变量,当没有共享范围时,将其作为参数传递。

您可以只传递res,然后在函数中的一个变量上同时访问querysend


出于分离关注点的目的,您最好改为传递回调。

那么do_search 只需要知道执行一个查询然后运行一个函数。这使它更通用(因此可重用)。

searcher.do_search(res.query, function (data) {
    res.send(...);
});

function do_search(query, callback) {
    callback(...);
} 

【讨论】:

  • 传递回调绝对是要走的路。 +1 建议。
  • 感谢您的帮助。我确实最终修改了我的 do_search 函数以接受回调,并且效果很好。
  • 这能回答问题吗?为什么示例中没有包含app.get,这是有问题的函数?
  • @nobar — 是的。因为从问题中逐字复制一堆代码是没有意义的;这只会使发现差异变得更加困难。
【解决方案2】:

现有答案完全有效,您也可以使用 ES2017 以来的 async/await 关键字。使用你自己的函数:

app.get('/search', async(req, res, next) {
  try {
    const answer = await searcher.do_search(req.query);
    res.send(answer);
  }
  catch(error) {
    return next(error);
  }
});

【讨论】:

    猜你喜欢
    • 2019-09-30
    • 2021-04-28
    • 2015-12-28
    • 2022-01-19
    相关资源
    最近更新 更多