首页 > 解决方案 > 在依赖于顺序响应的 MySQL 的两个查询之间注入 API 调用

问题描述

在我的后端 Node.js Express API 上,我需要连接到 MySQL 数据库,运行查询以获取一些信息。然后使用该信息调用外部 API。最后,在得到响应后,我需要在对我的数据库的第二次查询中使用外部信息。

我有一个功能目前可以完成所描述的任务,但在我的 Chrome 开发工具中,该请求永远不会被标记为已解决。这导致我在前端的承诺永远不会转移到其链中的下一个函数。

app.get('/api/update/:id', (req, res) => {
    const ID = req.params.id;
    connectionPool.getConnection((err, connection) => {
        if (err) {throw err;}
        const queryA = `SELECT infoA FROM table WHERE id = "${ID}"`;
        connection.query(queryA, (error, results, fields) => {
            const infoA = results[0].infoA;
            externalAPICall(infoA).then(res => {
                let infoB = res;
                const queryB = `UPDATE table SET infoB = "${infoB}" WHERE id = "${ID}"`;
                connection.query(query);
                connection.release();
            });
        });
    })
})

然后在前端,向这个 API 路由发送请求

updateInfo = (id) => {
    axios.get(`${API_ROOT}/api/update/${id}`)
    .then(res => {
        this.getAllInfo();
    });
}

我希望前端触发对api/update/id路由的请求,并从数据库中选择 infoA,用于信息 B 的外部 API 调用,然后将 infoB 更新到数据库中。在前端收到确认完成后,它将运行一个函数来查询函数中更新信息的完整表getAllInfo

现在,我的表成功地从外部 API 更新了自身,但是前端没有收到来自 API 的响应,所以它似乎永远不会继续进行getAllInfo函数调用。我已经尝试res.status(200).send(results)输入我的 API 路由,但是如果它太早,或者如果它在最后,它会给出一个错误,说res没有定义。

我觉得我错过了一些非常小的东西,可以让它全部工作。

标签: mysqlnode.jsexpress

解决方案


您没有从请求处理程序发送任何响应。当您的请求处理程序代码完成其工作时,您需要一个res.send(...)或一个。res.json(...)

而且,您需要更改以下参数:

externalAPICall(infoA).then(res => { ...});

到某个参数名称,而不是res因为它隐藏了res您需要与res.send()or一起使用的更高范围res.json()

你可以这样做:

app.get('/api/update/:id', (req, res) => {
    const ID = req.params.id;
    connectionPool.getConnection((error, connection) => {
        if (error) {
            console.log(err);
            res.sendStatus(500);
            return;
        }
        const queryA = `SELECT infoA FROM table WHERE id = "${ID}"`;
        connection.query(queryA, (error, results, fields) => {
            if (error) {
                console.log(err);
                res.sendStatus(500);
                return;
            }
            const infoA = results[0].infoA;
            externalAPICall(infoA).then(infoB => {
                const queryB = `UPDATE table SET infoB = "${infoB}" WHERE id = "${ID}"`;
                connection.query(query, (error, results, fields) => {
                    if (error) {
                        console.log(err);
                        res.sendStatus(500);
                    } else {
                        res.send("success");
                    }
                    connection.release();
                });

            });
        });
    })
})

注意:如果您在 mysql2 接口中使用 Promise 接口,这可能更易于编码、集中处理错误和维护。


推荐阅读