問題描述
AWS Lambda 函數全局變量 (AWS Lambda function global variables)
我正在用 JavaScript (Node.js) 編寫一個 AWS Lambda 函數,該函數通過 AWS 開發工具包與 CodeCommit 交互。
服務之間的通信按預期工作,我正在 CodeCommit 函數中獲取數據,但是當我想在函數之外使用這些數據時,就會出現我面臨的問題。
我嘗試了兩種方法:
1。全局變量
代碼:
var aws = require('aws‑sdk');
var codecommit = new aws.CodeCommit({ apiVersion: '2015‑04‑13' });
var repoName = ''; // Declared my global variable here
exports.handler = function(event, context) {
var commitId = "69a5f8eeba340d71ba41b8f20d77cc20b301ff52"
var repository = "my‑repository"
var params = {
repositoryName: repository
};
codecommit.getRepository(params, function(err, data) {
if (err) {
console.log(err);
var message = "Error getting repository metadata for repository " + repository;
console.log(message);
context.fail(message);
} else {
console.log('Repository Name:', data.repositoryMetadata.repositoryName); // Shown with data
repoName = data.repositoryMetadata.repositoryName; // Setting the variable
console.log('Account Id:', data.repositoryMetadata.accountId); // Shown with data
}
});
console.log(repoName); // Shown as blank in the output
};
輸出:
最後寫入的“console.log” 是第一個打印在執行結果中,但顯示為空白。然後打印另外兩個console.log(在函數內),並顯示數據。
2。函數
代碼:
var aws = require('aws‑sdk');
var codecommit = new aws.CodeCommit({ apiVersion: '2015‑04‑13' });
exports.handler = function(event, context) {
var commitId = "69a5f8eeba340d71ba41b8f20d77cc20b301ff52"
var repository = "my‑repository"
var repoData = getRepository(repository)
console.log('Repository Name:', repoData.repositoryName);
console.log('Account Id:', repoData.accountId);
};
function getRepository(repository) {
var params = {
repositoryName: repository
};
codecommit.getRepository(params, function(err, data) {
if (err) {
console.log(err);
var message = "Error getting repository metadata for repository " + repository;
console.log(message);
context.fail(message);
} else {
var repoData = {};
repoData.repositoryName = data.repositoryMetadata.repositoryName;
repoData.accountId = data.repositoryMetadata.accountId;
console.log(repoData); // Shows output in execution results when lines 11 & 12 are commented
return repoData;
}
});
}
輸出:
{
"errorType": "TypeError",
"errorMessage": "Cannot read property 'repositoryName' of undefined",
"trace": [
"TypeError: Cannot read property 'repositoryName' of undefined",
" at Runtime.exports.handler (/var/task/index.js:57:46)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
]
}
結論
這些方法都不起作用。數據始終在函數內可見,但從不在函數外。我懷疑函數外部的代碼在函數本身之前執行,我想知道我是否可以讓代碼在執行 console.log 之前等待函數已經執行(以及之後的其他操作)。或者也許我在另一個層面上錯了?
參考解法
方法 1:
You are using a callback model, in which case the console.log
in the first example is being hit before the code in the callback. A better option would be to use async/await
.
var aws = require('aws‑sdk');
var codecommit = new aws.CodeCommit({ apiVersion: '2015‑04‑13' });
var repoName = ''; // Declared my global variable here
exports.handler = async function(event, context) {
var commitId = "69a5f8eeba340d71ba41b8f20d77cc20b301ff52"
var repository = "my‑repository"
var params = {
repositoryName: repository
};
var data = await codecommit.getRepository(params).promise();
console.log('Repository Name:', data.repositoryMetadata.repositoryName); // Shown with data
repoName = data.repositoryMetadata.repositoryName; // Setting the variable
console.log('Account Id:', data.repositoryMetadata.accountId); // Shown with data
console.log(repoName);
};
</code></pre>
Notice that I'm not catching the error here, but if you wanted to you can use a try/catch
block. Just be sure you throw
a new error in that case if you want the function to fail.
(by GuillaumeExia、Jason Wadsworth)
參考文件