函数不断返回未定义(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 condition:checkEmail
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
我正在使用 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 condition:checkEmail
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