Writing Asynchronous Lambda Functions
Thanks to the introduction of NodeJS 8.10 runtime environments, it's now possible to create asynchronous AWS Lambda functions. We can use serverless and specify the runtime like this:
provider: name: aws runtime: nodejs8.10
serverless.yml
While they're could be some breaking changes in the upgrade, it may be worth the risk. The benefits of using NodeJS 8.10 are pretty clear. Here are some of those main benefits.
NodeJS 8.10
A number of features have been introduced into the LTS that significantly affect the way you can write lambda functions. A complete breakdown of the major features can be found here. In short, the major improvements are:
- Asynchronous Hooks
- New ES8 Features and Reserved Keywords
- Significant Performance Improvements
- HTTP/2
Converting An Existing Lambda Function
Because the async/await syntax is available in this runtime environment, we can leverage the information from the previous article and apply it to our current lambda functions. Let's take a look at how we can incorporate these to our FaaS.
Here is our initial function which leverages promises and callbacks.
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
exports.handler = (event, context, callback) => {
let localCompaniesByGeoCoordsPromise =
lambda.localCompaniesByGeoCoordsPromise().promise();
localCompaniesByGeoCoordsPromise.then(
(data) => {
callback(null, data);
},
(err) => {
console.log(err);
callback(err);
}
);
};
Step 1: Removing Callbacks
A noticeable difference between the previous signature and the current one is that the callbacks are removed.
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
exports.handler = (event, context) => {
}
A side note regarding this is that callbacks are still fully supported, however, avoiding them means easier and cleaner code. Why is that? With callbacks, you must be familiar with the nature of nested callbacks and their more complex syntax as highlighted in the previous article. They are more challenging to write and often complicate the readability of code.
Step 2: Declaring The Function Async
We declare the handler with the async keyword:
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
exports.handler = async (event, context) => {
}
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 asyncfunction's execution and returns the resolved value.
It's an important consideration that you should be aware with. The await keyword can only be used within the context of an async function. That means if you try to use an await outside of this, you'll see an error.
Step 3: Refactoring The Promise
Next, we can refactor the code within the lambda function here:
let localCompaniesByGeoCoordsPromise =
lambda.localCompaniesByGeoCoordsPromise().promise();
localCompaniesByGeoCoordsPromise.then(
(data) => {
callback(null, data);
},
(err) => {
console.log(err);
callback(err);
}
);
The await keyword can be leveraged here to condense the code into one line. Essentially, we will wait for the promise to resolve and continue execution once it has either been fulfilled or rejected.
try{
let data
= await lambda.localCompaniesByGeoCoordsPromise().promise();
} catch (err) {
console.log(err);
return err;
}
return data;
Notice, the code is written in a way where there is no nesting or chaining of promises. This is the beauty of using these new features. The code can be written in, what looks like a synchronous manner, even though its not!
Here's what our function should look like now:
Async Lambda Functions
let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();
exports.handler = async (event) => {
try {
let data
= await lambda.localCompaniesByGeoCoordsPromise().promise();
}catch (err) {
console.log(err);
return err;
}
return data;
};
Conclusion
This quick write up is all about leveraging the new features and performance improvements that you can incorporate into your next lambda function. This will hopefully open up some ideas for you when it comes to your next asynchronous task.
As Always, Thanks for Reading.