首页 > 解决方案 > 将异步函数返回值分配给 Node.JS 中的变量

问题描述

我在下面有一个函数,它从 DynamoDB 中获取数据,然后在评估条件时返回 true 或 false。此功能将用于进行简单的检查并确定用户的数据访问权限等。

我怎样才能让这个函数做类似的事情:

var auth = aliasHasRole('foo','bar')
console.log(auth) // prints value passed down by aliasHasRole().

我想我必须在返回之前将其声明为async并添加await,但没有运气,然后做了aliashHasRole('foo','bar').then( (x) => { auth = x}),但它返回了undefined


这是完整的代码:

var AWS = require('aws-sdk');
AWS.config.update({
    region: 'us-west-2',
    accessKeyId: "xxx",
    secretAccessKey: "xxx",
});
const docClient = new AWS.DynamoDB.DocumentClient();


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

    docClient.query(params).promise()
        .then(
            (data) => {
                //this line below returns true or false, how can I get I pass this value so I can return it from the aliasHasRole as true or false?
                console.log(data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false);
                return data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
            })
        .catch((err) => {
            console.log(err)
        })
};

var auth;
aliasHasRole("xxx","TeamManager");//should return true or false just like it logs it to the console.
//Do something to assign functions value to var auth.
console.log(auth) //print value passed by function...

//How can I assign this value to a variable? as in var auth = aliasHasTole('foo','bar') // auth is now true or false.

标签: node.jsasynchronousasync-awaitamazon-dynamodbaws-sdk-nodejs

解决方案


您没有正确使用async/await关键字。像这样修改您的函数并尝试。

var AWS = require('aws-sdk');
AWS.config.update({
    region: 'us-west-2',
    accessKeyId: "xxx",
    secretAccessKey: "xxx",
});
const docClient = new AWS.DynamoDB.DocumentClient();

// you can use async and await like this
let aliasHasRole = async function (an_alias, a_role) {

    try {
        const params = {
            TableName: 'xxx',
            KeyConditionExpression: '#alias= :alias AND #Role= :Role',
            ExpressionAttributeNames: {
                '#alias': 'alias',
                '#Role': 'Role'
            },
            ExpressionAttributeValues: {
                ':alias': an_alias,
                ':Role': a_role,
            }
        };

        // this will resolve the value 
        let data = await docClient.query(params).promise()
        return data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false;
    }
    catch (err) {
        //this is equivalent .catch statement
        console.log(err)
    }
};
// This has to be self executing function in case of async await
(async () => {
    var auth = await aliasHasRole("xxx", "TeamManager");
    // This will print the value of auth which will be passed from the aliasHasRole ie. True or False
    console.log(auth) //print value passed by function aliasHasRole...
})()

您也可以在没有async/await 的情况下使用它


var AWS = require('aws-sdk');
AWS.config.update({
    region: 'us-west-2',
    accessKeyId: "xxx",
    secretAccessKey: "xxx",
});
const docClient = new AWS.DynamoDB.DocumentClient();

// you can use async and await like this
function aliasHasRole(an_alias, a_role) {

    const params = {
        TableName: 'xxx',
        KeyConditionExpression: '#alias= :alias AND #Role= :Role',
        ExpressionAttributeNames: {
            '#alias': 'alias',
            '#Role': 'Role'
        },
        ExpressionAttributeValues: {
            ':alias': an_alias,
            ':Role': a_role,
        }
    };

    // Return is the main part. The error was that you are not using the return key word with Promise that's why it was not working
    return docClient
        .query(params)
        .promise()
        .then(data => data.Items.length > 0 && data.Items[0].alias === an_alias && data.Items[0].Role === a_role ? true : false)
        .catch(error => {
            // You can handle the error here
            console.log(error)
        })
};


aliasHasRole("xxx", "TeamManager").then(auth => {
    // This will print the value of auth which will be passed from the aliasHasRole ie. True or False
    //print value passed by function...
    console.log(auth)
})


推荐阅读