简体   繁体   English

Node.js 和 Express:如何在异步操作后返回响应

[英]Node.js and Express: How to return response after asynchronous operation

I'm new to Node.js, so I'm still wrapping my head around asynchronous functions and callbacks.我是 Node.js 的新手,所以我仍然在关注异步函数和回调。 My struggle now is how to return a response after reading data from a file in an asynchronous operation.我现在的难题是如何在异步操作中从文件读取数据后返回响应。

My understanding is that sending a response works like this (and this works for me):我的理解是发送响应是这样的(这对我有用):

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

However, now I want to read a file, perform some operations on the data, and then return the results in a response.但是,现在我想读取一个文件,对数据执行一些操作,然后在响应中返回结果。 If the operations I wanted to perform on the data were simple, I could do something like this -- perform them inline, and maintain access to the res object because it's still within scope.如果我想对数据执行的操作很简单,我可以做这样的事情——内联执行它们,并保持对res对象的访问,因为它仍在范围内。

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

However, the file operations I need to perform are long and complicated enough that I've separated them out into their own function in a separate file.但是,我需要执行的文件操作既长又复杂,我已将它们分离到单独文件中的自己的函数中。 As a result, my code looks more like this:结果,我的代码看起来更像这样:

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

I need to call res.send in order to send the result.我需要调用res.send才能发送结果。 However, I can't call it directly in the function above, because do_search completes asynchronously.但是,我不能在上面的函数中直接调用它,因为do_search异步完成的。 And I can't call it in the callback to do_search because the res object isn't in scope there.我不能在do_search的回调中调用它,因为res对象不在那里。

Can somebody help me understand the proper way to handle this in Node.js?有人可以帮助我理解在 Node.js 中处理这个问题的正确方法吗?

To access a variable in a different function, when there isn't a shared scope, pass it as an argument. 要访问不同函数中的变量,当没有共享范围时,将其作为参数传递。

You could just pass res and then access both query and send on the one variable within the function. 您可以只传递res然后访问querysend函数中的一个变量。


For the purposes of separation of concerns, you might be better off passing a callback instead. 出于分离关注点的目的,您可能最好不要传递回调。

Then do_search only needs to know about performing a query and then running a function. 然后do_search只需要了解执行查询然后运行函数。 That makes it more generic (and thus reusable). 这使它更通用(因而可重复使用)。

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

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

The existing answers are perfectly valid, you can also use async/await keywords since ES2017.现有答案完全有效,您也可以使用自 ES2017 以来的 async/await 关键字。 Using your own function:使用你自己的函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM