- The function after
await someFunc()
need to return a promise. Otherwise it will not await and exit from the function. The function below will simply exit and won't wait till the background process is finished. Since async functions are waiting for Promises. The keyword await makes JavaScript wait until that promise settles and returns its result.
const hello4 = () => setTimeout(() => console.log('Hello from Hello4'), 5000)
const asycFunc = async() => {
await hello4()
return
}
But if do return a promise:
const hello4 = () => {
return new Promise(resolve => {
setTimeout(() => resolve(console.log('Hello from Hello4')), 2000)
})
}
const asycFunc = async() => {
await hello4()
return
}
// Hello from Hello4
- If something doesn't return a promise you need to promisify it. For instance, you can promisify the Amazon SDK by adding
.promise()
. So you can useasync/await
functions. The AWS.Request.promise method provides a way to call a service operation and manage asynchronous flow instead of using callbacks.
var s3 = new AWS.S3({apiVersion: '2006-03-01', region: 'us-west-2'});
var params = {
Bucket: 'bucket',
Key: 'example2.txt',
Body: 'Uploaded text using the promise-based method!'
};
var putObjectPromise = s3.putObject(params).promise();
putObjectPromise.then(function(data) {
console.log('Success');
}).catch(function(err) {
console.log(err);
});
- Use
try{} catch (error) {}
to do proper error handling
const hello4 = () => {
return new Promise(resolve => {
setTimeout(() => resolve(console.log('Hello from Hello4')), 2000)
})
}
const asycFunc = async() => {
try {
await hello4()
return
}
catch (error) {
console.log(error)
}
}
// Hello from Hello4
Note: An async function can contain an await expression that pauses the execution of the async function and waits for the passed Promise's resolution, and then resumes the async function's execution and returns the resolved value. The return value of an async function is implicitly wrapped in Promise.resolve
.
Below you can see an example how async and sync operations can be mixed together.
const AWS = require('aws-sdk');
exports.handler = async function(event, context, callback) {
const EC2 = new AWS.EC2();
const S3 = new AWS.S3();
try {
// Get some info about all instances.
const instancesData = await EC2.describeInstances().promise();
// Get instance IDs.
const instanceIds = [];
instancesData.Reservations.forEach(reservation => {
reservation.Instances.forEach(instance => {
instanceIds.push(instance.InstanceId);
});
});
// Iterate through each instance ID.
for (instanceId of instanceIds) {
// Create an S3 bucket.
await S3.createBucket({ Bucket: instanceId }).promise();
// Put an object into the newly created bucket.
await S3.putObject({ Bucket: bucketId, Key: 'hello.txt', Body: 'Hello world!' }).promise();
}
callback(null, 'Success!');
} catch (err) {
callback(err.message);
}
};
If you want don't want to use callback(null, 'success)
inside an async/await
function you need always to include try{}catch (err) {}
. Therefore there will be no need to include callback
, see example below:
exports.lambda_handler = async(event, context, callback) => {
try {
await dynamodb.putItem(params).promise()
return 'Works' // return a message a success message to the caller
}
catch (error) {
console.log(error)
return 'Error' // return an error to the caller
}
}
If you don't use async/await
lambda function you can exit the function by simply returing a promise that will be either resolved or rejected. Based on the resolution the caller will get the right message, see example below:
exports.handler = (event) => {
let params = {
TableName: TABLE_NAME
}
return dynamoDb.scan(params)
.promise()
.then(response => (processResponse(IS_CORS, response.Items)))
.catch(err => {
console.log(err);
return processResponse(IS_CORS, 'dynamo-error', 500);
})
}
// inside processResponse()
module.exports = (isCors, body, requestedCode) => {
const code = requestedCode || (body ? 200 : 204);
const headers = isCors ? {
'Access-Control-Allow-Headers': 'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Methods': 'OPTIONS,POST',
'Access-Control-Allow-Origin': process.env.CORS_ORIGIN,
'Access-Control-Max-Age': '86400',
'Content-Type': 'application/json'
} : { 'Content-Type': 'application/json' };
return {
statusCode: code,
body: JSON.stringify(body) || '',
headers: headers
};
};
The Node.js runtimes v6.10 and v8.10 support the optional callback parameter. You can use it to explicitly return information back to the caller. If you don't use callback in your code, AWS Lambda will call it implicitly and the return value is null. When the callback is called (explicitly or implicitly), AWS Lambda continues the Lambda function invocation until the event loop is empty.
exports.myHandler = function(event, context, callback) {
console.log("value1 = " + event.key1);
console.log("value2 = " + event.key2);
callback(null, "some success message");
// or
// callback("some error type");
}
This is a huge magic, i must take 3 days and it still not run correctly :(