如何在多个异步调用中向 NodeJS 中的数据库发送响应?

Posted

技术标签:

【中文标题】如何在多个异步调用中向 NodeJS 中的数据库发送响应?【英文标题】:How to send response in mid of multiple async calls to database in NodeJS? 【发布时间】:2019-03-03 16:44:34 【问题描述】:

需要终止POST函数并发送Error: something作为响应,而不终止程序。

示例for-loop:

for (let i = 0; i < req.body.listoftouristsbyid.length; i++) 
  client.query("SELECT tourists.id FROM tourists WHERE tourists.id = " + req.body.listoftouristsbyid[i], function(err, result) 
    done();
    if (result.rows.length === 0) 
      console.log("Tourist " + req.body.listoftouristsbyid[i] + " you want to add does not exist");
      res.status(500);
      return res.render("Bad listoftoutistbyid request, student with id " + i + " does not exist");
    
  )

我应该写什么来代替 return res.render,这样 POST 将不起作用,函数将终止并返回错误代码作为响应,但不会导致程序崩溃,因此我可以稍后发送更多请求?

【问题讨论】:

我不会向 DB 发出大量请求,而是通过将它们与 OR 组合来进行一个查询 ... 我希望你做输入验证。 你可以使用try ... catch声明。 这意味着您网站的任何访问者都可以使用您的数据库xkcd.com/327 好吧,不要在循环中做很多查询,并在每个查询返回后尝试发送响应。只能有一个响应。 【参考方案1】:

您可以为此使用async-await,因为它在PromiseGenerators 等异步调用处理程序中得到了高度使用。

这是一个示例代码:

app.post('/APIendpoint', async (req, res) => 

    let listoftouristsbyid      = req.body.listoftouristsbyid;

    let dbResult = [];

    // Can put this whole for loop inside try too. Then success response will also be inside try after for-loop
    for (let i = 0; i < listoftouristsbyid.length; i++) 

        try 
            let result = await callDB( "SELECT tourists.id FROM tourists WHERE tourists.id = " + listoftouristsbyid[i] );
            dbResult.push(result);
        
        catch (err) 

            console.log("Tourist " + listoftouristsbyid[i] + " you want to add does not exist");

            res.status(500);
            return res.send("Bad listoftoutistbyid request, student with id " + i + " does not exist");

        
    

    console.log("Successfully fetched all records ", dbResult);

    res.status(200);
    return res.send(dbResult);

);

function callDB(query) 

    return new Promise ( (resolve, reject) => 
        client.query(query, function(err, result) 

            if (result.rows.length === 0) 
                reject("not found");
             else 
                resolve(result.rows);
            

        )
    );

【讨论】:

【参考方案2】:

尝试使用async.map 来解决您的问题。 for 循环不适用于异步函数。

async.map(
    req.body.listoftouristsbyid, 
    function(touristId, callback) 
        client.query("<query>", function(err, result) 
            if (result.rows.length === 0) 
                callback(new Error("not found"));
            
            callback(null, result);
        );
    ,
    function(err, result) 
        // send response here.
     
);

【讨论】:

以上是关于如何在多个异步调用中向 NodeJS 中的数据库发送响应?的主要内容,如果未能解决你的问题,请参考以下文章

在异步套接字中向特定客户端发送数据

如何在 JQuery 验证插件 addmethod() 中向服务器端发送异步 AJAX 调用

nodejs中的多个异步mongo请求

使用异步和请求包(NodeJS / Express)进行多个 API 调用

nodejs异步调用async

Lambda中的NodeJS异步未运行所有条目