DynamoDB returns 未定义但在 console.log() 中记录数据,异步问题?

DynamoDB returns undefined but does log data in console.log(), async issue?

我有一个函数可以使用 docClient.query() 从 DynamoDB 获取一些数据。我能够检索数据并将其打印在控制台上,例如 console.log(data)),但如果我尝试 return data,我总是无法定义。

我认为 function (err,data){ ... }query() 函数的回调,希望它在 returning 之前等待值可用。

很明显,我是 AWS SDK 和异步函数的新手,找不到以我需要的方式使用 return 的文档。

我只需要 aliasHasRole 到 return isAuthorized JSON 这样我就可以在函数之外的其他地方使用它。

function aliasHasRole(an_alias, a_role) {
    const params = {
        TableName: 'xxxxxxx',
        KeyConditionExpression: '#alias= :alias AND #Role= :Role',
        ExpressionAttributeNames: {
            '#alias': 'alias',
            '#Role': 'Role'
        },
        ExpressionAttributeValues: {
            ':alias': an_alias,
            ':Role': a_role,
        },
    };

    docClient.query(params, function (err, data) {
        if (err) {
            console.log("Error when attempting table query, see below:\n\n" + 
JSON.stringify(err, null, 2));
            return err;
        } else {
            var isAuthorized = data.Count === 1 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
            console.log(1,'Access', isAuthorized ? 'Granted' : 'Denied', 'for alias "' + an_alias + '".\n');
            return isAuthorized; //always returns undefined
        }
    })
}

console.log(aliasHasRole("fooAlias","barRole")) // returns undefined.

这肯定是与异步代码相关的问题。如果你能够使用 docClient.queryasync/await 语法,那么你可以等待它的执行和 return 值根据它的结果。如果需要知道 err 值(如果存在),您还可以使用 Promise 语法。然后你也可以在你的函数中使用resolve/reject

async/await 语法的解决方案:

async function aliasHasRole(an_alias, a_role) {
    const params = {
        TableName: 'xxxxxxx',
        KeyConditionExpression: '#alias= :alias AND #Role= :Role',
        ExpressionAttributeNames: {
            '#alias': 'alias',
            '#Role': 'Role'
        },
        ExpressionAttributeValues: {
            ':alias': an_alias,
            ':Role': a_role,
        }
    };
    const data = await docClient.query(params);
    if (!data) return false;
    const isAuthorized = data.Count === 1 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
    return isAuthorized;
};

aliasHasRole("fooAlias", "barRole").then(console.log).catch(console.log);

更新

真正有用的是让您的查询成为 .promise() 的承诺。然后可以使用 then/catch 语法轻松执行和处理它。