函数不断返回未定义(DynamoDB)

Function keeps returning undefined (DynamoDB)

我正在使用 AWS DynamoDB 并尝试在 table 中查询电子邮件地址。我想看看 table 中有多少相同的电子邮件。但出于某种原因,当我 运行 下面的函数时,我得到 undefined.

let docClient = new AWS.DynamoDB.DocumentClient();

function checkEmail(email) {
    var params = {
        TableName: "Users",
        IndexName: "email",
        KeyConditionExpression: "email=:email",
        ExpressionAttributeValues: {
            ":email": email
        }
    }
    var emails = 0;
    docClient.query(params, function (err, data) {
        if (err) {
            return -1;
        }
        else {
            emails = data.ScannedCount;
        }
    });

    return emails;
}

我认为它可能必须在 table 被完全查询之前完成一些功能。但我不知道该如何解决这个问题 (async/await?)。

这里有一个race conditioncheckEmail returns早于docClient.query调用它的回调,因为docClient.query是异步的,但是checkEmail不是。

您需要做的是将 checkEmail 也定义为异步工作,— 在这种情况下,通过使用 Promises and async / await syntax. As Richard Dunn suggested in the comment, AWS does provide such promise in this case,因此可以无缝地使用它:

const docClient = new AWS.DynamoDB.DocumentClient();

async function checkEmail(email) {
    const params = {
        TableName: "Users",
        IndexName: "email",
        KeyConditionExpression: "email=:email",
        ExpressionAttributeValues: {
            ":email": email,
        },
    };

    try {
        const data = await docClient.query(params).promise();
        return data.ScannedCount;
    } catch (error) {
        console.error(error);
        return -1;
    }
}

现在,由于该函数现在是异步的,您不只是调用它,您还要等到它完成作业 — 并且只有 然后 获取结果:

checkEmail(email).then((emails) => {
    // `emails` is a number
});

回调函数在函数returns之后运行。把函数改成这样:

let docClient = new AWS.DynamoDB.DocumentClient();

function checkEmail(email) {
    return new Promise(function(resolve, reject) {
        var params = {
            TableName: "Users",
            IndexName: "email",
            KeyConditionExpression: "email=:email",
            ExpressionAttributeValues: {
                ":email": email
            }
        }
        docClient.query(params, function (err, data) {
            if (err) {
                reject(err); //Error
            }
            else {
                resolve(data.ScannedCount); //OK
            }
        });
    });
}

您还需要更改调用函数的位置;来自:

checkEmail(someValue);

其中之一:

//Change the function you're calling the function from to an ASYNC function:
async function myFunction() {
    await checkEmail(someValue);
    //DO SOMETHING
}

或者,如果您做不到:

checkEmail(someValue).then(function(returnValue) {
    //DO SOMETHING HERE
});
//NOT HERE