首页 > 解决方案 > 与 Promise 结合使用时,Async/await 调用返回 undefined

问题描述

我遇到一个问题,对我的数据库的异步调用返回未定义。函数“findOne”从数据库中检索一行,但该.then(...函数在该行返回之前执行。

我尝试更改我在 DB 函数findOne中返回的内容,并在函数调用中添加“等待”。我也尝试过使用Promise.resolve(db.findOne({requestbody}).then(...,但也没有运气。

这是db.findOne方法

const findOne = async (req) => {
    const { teamId, channelId, isClosed } = req;
    return db.query('SELECT * FROM polls where team_id= $1 and channel_id =$2 and is_closed = $3 LIMIT 1',
        [teamId, channelId, isClosed],
        (error, results) => {
            if (error) {
                throw error;
            }
            console.log("\nDBRes: \n", results.rows[0])
            return results.rows[0];
        }
    );
};

这是我调用函数的地方

app.post('/', (req, res) => {
    const slashCommand = req.body.command;
    switch (slashCommand) {
//...
//... Some other code
//...
        case 'results':
            db.findOne({
                teamId: requestBody.team_id,
                 channelId: requestBody.channel_id,
                 isClosed: false,
            })
            .then((row) => {
                 console.log(row);
                 const poll = pollFuncs.getPollfromResultRow(row);
                 const displayText = pollFuncs.getFormattedPollResults(poll);
                 res.status(200).send({
                     text: displayText,
                 });
             });
         break;
//... The rest of the function

这是我得到的日志。注意*我目前正在.then(...)函数内部和pollFuncs.getPollfromResultRow(row);函数内部记录“行”对象

Bot is listening on port 3000
undefined
undefined
(node:14000) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property `id` of 'undefined' or 'null'.
    at Object.getPollfromResultRow (C:\Users\ztb0504\Documents\Projects\Node\werewolfmod\pollFunctions.js:97:125)
    at db.findOne.then (C:\Users\ztb0504\Documents\Projects\Node\werewolfmod\index.js:59:56)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:14000) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:14000) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

DBRes:
 { id: '22',
  poll_title: 'This is a new Pollstgresql',
  //The rest of the expected data....
 }

我将不胜感激有关如何使其按预期返回数据的任何指导。谢谢!

标签: javascriptnode.jsasynchronousasync-await

解决方案


你混合了普通的回调和承诺,这给你带来了问题。如果你不这样做会容易很多。

如果你将一个普通的回调传递给db.query(),那么它不会返回一个承诺。实际上,它不会返回任何内容 ( undefined)。所以,当你这样做时return db.query(),你所做的就是返回undefined

改成这样:

const findOne = async (req) => {
    const { teamId, channelId, isClosed } = req;
    return db.query('SELECT * FROM polls where team_id= $1 and channel_id =$2 and is_closed = $3 LIMIT 1',
        [teamId, channelId, isClosed]).then(results) => {
            console.log("\nDBRes: \n", results.rows[0])
            return results.rows[0];
    });
};

如果查询中有任何错误,您还需要在请求处理程序中进行错误处理。Promise 处理应该总是有一个.catch()地方来处理错误:

                case 'results':
                    db.findOne({
                        teamId: requestBody.team_id,
                        channelId: requestBody.channel_id,
                        isClosed: false,
                    }).then((row) => {
                            console.log(row);
                            const poll = pollFuncs.getPollfromResultRow(row);
                            const displayText = pollFuncs.getFormattedPollResults(poll);
                            res.status(200).send({
                                text: displayText,
                            });
                    }).catch(err => {
                            console.log(err);
                            res.sendStatus(500);
                    });
                    break;

推荐阅读