本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
AWS Lambda Node.js 中的函數處理常式
Lambda 函數處理常式是您的函數程式碼中處理事件的方法。當有人呼叫您的函數時,Lambda 會執行處理常式方法。函數會執行,直到處理常式傳回回應、結束或逾時為止。
下列範例函數會記錄事件物件的內容,並傳回記錄檔的位置。
- ES module handler
-
export const handler = async (event, context) => {
console.log("EVENT: \n" + JSON.stringify(event, null, 2));
return context.logStreamName;
};
- CommonJS module handler
-
exports.handler = async function (event, context) {
console.log("EVENT: \n" + JSON.stringify(event, null, 2));
return context.logStreamName;
};
當您設定函數時,處理常式的設定值就是檔案名稱,以及已匯出之處理常式方法的名稱,並且以點分隔。主控台中的預設值,例如在此指南中為 index.handler
。這表示 handler
方法是透過 index.js
檔案匯出的。
執行程序會將引數傳送至處理常式方法。第一個引數是 event
物件,其中包含來自叫用端的資訊。呼叫者會在呼叫 Invoke 時,以 JSON 格式的字串傳遞此資訊,然後執行時間將它轉換為物件。當 AWS 服務叫用您的函數時,事件結構會因服務而異。
第二個引數為 內容物件,其中包含有關呼叫、函式和執行環境的資訊。在上述範例中,該函式從內容物件取得日誌串流的名稱並傳回給叫用端。
您也可以使用回呼引數 (此引數是您在非同步處理常式中呼叫來傳送回應的函數)。建議您使用非同步/等待 (而不是回呼)。非同步/等待改善了可讀性、錯誤處理及效率。如需有關非同步/等待和回呼之間差異的詳細資訊,請參閱 使用回呼。
命名
當您設定函數時,處理常式的設定值就是檔案名稱,以及已匯出之處理常式方法的名稱,並且以點分隔。在控制台中創建的功能和本指南中的示例的默認值是index.handler
。這表示從index.js
或index.mjs
檔案匯出的handler
方法。
如果要在主控台中使用不同檔案名稱或函數處理常式名稱建立函數,您必須編輯預設處理常式名稱。
變更函數處理常式名稱的方式 (主控台)
-
開啟 Lambda 主控台的函數頁面,然後選擇您的函數。
-
選擇 程式碼 索引標籤。
-
向下捲動至執行時間設定窗格,並選擇編輯。
-
在處理常式中,輸入函數處理常式的新名稱。
-
選擇 儲存 。
使用 async/await
如果您的程式碼執行非同步任務,請使用非同步/等待模式,以確保處理常式能順利完成執行。非同步/等待是一種在 Node.js 中撰寫非同步程式碼的簡潔可讀模式,無需巢狀回呼或鏈結承諾。您可以透過非同步/等待模式撰寫讀起來像同步程式碼的程式碼,同時仍維持非同步和非封鎖的特性。
async
關鍵字會將函數標記為非同步,且 await
關鍵字會暫停函數的執行,直到 Promise
獲得解決為止。
請務必等待非同步事件完成。如果函數在非同步事件完成之前傳回,則函數可能會失敗或導致應用程式中的非預期行為。當 forEach
迴圈包含非同步事件時,可能會發生這種情況。forEach
迴圈期望一個同步呼叫。如需更多資訊,請參閱 Mozilla 文件中的 Array.prototype.forEach()。
- ES module handler
-
範例 - 具有 async/await 的 HTTP 請求
此範例使用fetch
,在以後的執行階段中nodejs18.x
均可使用。
const url = "https://aws.amazon.com/";
export const handler = async(event) => {
try {
// fetch is available in Node.js 18 and later runtimes
const res = await fetch(url);
console.info("status", res.status);
return res.status;
}
catch (e) {
console.error(e);
return 500;
}
};
- CommonJS module handler
-
範例 - 具有 async/await 的 HTTP 請求
const https = require("https");
let url = "https://aws.amazon.com/";
exports.handler = async function (event) {
let statusCode;
await new Promise(function (resolve, reject) {
https.get(url, (res) => {
statusCode = res.statusCode;
resolve(statusCode);
}).on("error", (e) => {
reject(Error(e));
});
});
console.log(statusCode);
return statusCode;
};
下一個範例會使用非同步/等待來列出您的 Amazon Simple Storage Service 儲存貯體。
使用此範例前,請確定函數的執行角色具有 Amazon S3 讀取許可。
- ES module handler
-
範例 — AWS SDK v3 與異步/等待
此範例使用 AWS SDK for JavaScript v3,它可在以後的執行階段中nodejs18.x
使用。
import {S3Client, ListBucketsCommand} from '@aws-sdk/client-s3';
const s3 = new S3Client({region: 'us-east-1'});
export const handler = async(event) => {
const data = await s3.send(new ListBucketsCommand({}));
return data.Buckets;
};
- CommonJS module handler
-
範例 — 具有異步/等待的 AWS SDK v2
此範例會使用 AWS SDK for JavaScript v2 (包含在 nodejs16.x
Lambda 執行期之中)。
const AWS = require('aws-sdk')
const s3 = new AWS.S3()
exports.handler = async function(event) {
const buckets = await s3.listBuckets().promise()
return buckets
}
使用回呼
建議您使用 非同步/等待 來宣告函數處理常式,而不是使用回呼。非同步/等待是更好的選擇,以下列出幾項原因:
-
可讀性: 非同步/等待程式碼比回呼程式碼更容易閱讀和理解,回呼程式碼可能很快就會變得難以理解,並引發回呼地獄。
-
偵錯和錯誤處理: 回呼型程式碼的偵錯工作難度可能不低。呼叫堆疊可能會變得難以理解,且可能會很容易接受錯誤。您可以透過非同步/等待使用 try/catch 區塊來處理錯誤。
-
效率: 回呼通常需要在程式碼的不同部分之間進行切換。非同步/等待可以減少切換環境的次數,進而產生更有效率的程式碼。
在處理常式中使用回呼時,函數將繼續執行,直到 事件迴圈 清空或函數逾時為止。直到完成所有的事件迴圈任務,回應才會傳送到叫用端。如果函式逾時,便會傳回錯誤。您可以設定內容,將執行階段設定為立即傳送回應。 callbackWaitsForEmptyEventLoop假的。
回乎函式需要兩個引數,一個 Error
和回應。回應物件必須與 JSON.stringify
相容。
以下範例函式檢查 URL 及傳回狀態碼給叫用端。
- ES module handler
-
範例 - 具有 callback 的 HTTP 請求
import https from "https";
let url = "https://aws.amazon.com/";
export function handler(event, context, callback) {
https.get(url, (res) => {
callback(null, res.statusCode)
;
}).on("error", (e) => {
callback(Error(e))
;
});
}
- CommonJS module handler
-
範例 - 具有 callback 的 HTTP 請求
const https = require("https");
let url = "https://aws.amazon.com/";
exports.handler = function (event, context, callback) {
https.get(url, (res) => {
callback(null, res.statusCode)
;
}).on("error", (e) => {
callback(Error(e))
;
});
};
在下一個範例中,Amazon S3 的回應會在可用時立即傳回給啟動程式。逾時的事件迴圈已凍結,並繼續執行下一個時間叫用的函式。
使用此範例前,請確定函數的執行角色具有 Amazon S3 讀取許可。
- ES module handler
-
範例 — AWS 軟體開發套件 callbackWaitsFor EmptyEventLoop
此範例使用 AWS SDK for JavaScript v3,它可在以後的執行階段中nodejs18.x
使用。
import AWS from "@aws-sdk/client-s3";
const s3 = new AWS.S3({});
export const handler = function (event, context, callback) {
context.callbackWaitsForEmptyEventLoop
= false
;
s3.listBuckets({}, callback);
setTimeout(function () {
console.log("Timeout complete.");
}, 5000);
};
- CommonJS module handler
-
範例 — 具有 AWS 軟體開發套件 callbackWaitsFor EmptyEventLoop
此範例會使用 AWS SDK for JavaScript v2 (包含在 nodejs16.x
Lambda 執行期之中)。
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
exports.handler = function (event, context, callback) {
context.callbackWaitsForEmptyEventLoop
= false
;
s3.listBuckets(null, callback);
setTimeout(function () {
console.log("Timeout complete.");
}, 5000);
};