与promises结合使用时,异步/等待调用返回未定义

时间:2019-08-10 15:55:42

标签: javascript node.js asynchronous async-await

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

我尝试更改在DB函数findOne中返回的内容,并在函数调用上添加了“ await”。我也尝试使用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....
 }

我希望您能获得有关如何按预期返回数据的任何指导。 谢谢!

1 个答案:

答案 0 :(得分:0)

您混用了简单的回调和诺言,这给您带来了麻烦。如果不这样做,会容易得多。

如果您将简单的回调传递给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];
    });
};

如果查询中有任何错误,您还需要在请求处理程序中进行错误处理。承诺处理应该几乎总是在某个地方有.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;