How to wrap a TypeScript JS callback with async await
Thu, 25 Feb 2021 00:00 UTC by garethbrown
I find that at times the standard TypeScript/JavaScript callback pattern can make code hard to read and manage. To alleviate this problem, we can wrap callbacks with promises to synchronise the call. Going a step further, we can implement async / await to further improve code readability. This is especially true if like me, your primary programming language is OO like C# or Java.
In the below example, I’m working with NeDB, as JS database. Operations in NeDB follow the standard callback pattern. Standard callback pattern in the docs looks like this:
db.findOne({'name': 'draupnir'}, function (err, doc) {
console.log('findOne callback: err, doc', [err, doc]);
});
In the async / await version below, we create an async function that wraps a promise, allowing us to call await to synchronise on the result. To allow for error handling in case promise reject() is called, we wrap the await in a try-catch-finally block.
In the standard promise version, we simply use findOnePromise.then()
to inspect the result.
So, depending on your preference, you have some options …
///////////////////////
// async / await vesion
///////////////////////
let findOnePromiseFn = async (obj):Promise<any> => {
return new Promise((resolve, reject) => {
db.findOne(obj, function (err, doc) {
if(err)
{
reject(err);
}
else
{
resolve(doc);
}
});
})
}
// Trigger the function
let findOnePromise = findOnePromiseFn({'name': 'draupnir'});
// Potentially do other stuff ...
// Await the result
try
{
let findOnePromiseResult = await findOnePromise;
console.log('findOnePromiseResult', findOnePromiseResult);
}
catch (e)
{
console.log('findOnePromiseResult (Error)', e);
}
finally
{
// Any clean up
}
/////////////////////////////////
// standard promise based version
/////////////////////////////////
let findOnePromisFn = () => {
return new Promise((resolve, reject) => {
db.findOne({'name': 'draupnir'}, function (err, doc) {
if(err)
{
reject(err)
}
else
{
resolve(doc);
}
});
})
}
findOnePromisFn().then(
value => {
// Success
console.log('findOnePromiseResult', value);
},
reason => {
// Error
console.error('findOnePromiseResult (Error)', reason);
}
);
//////////////////////////////////
// Standard async callback version
//////////////////////////////////
db.findOne({'name': 'draupnir'}, function (err, doc) {
console.log('findOne callback: err, doc', [err, doc]);
});
-
Web Analytics
-
.NET
-
API Versioning and Basic UI Authentication with OpenAPI (Swagger / Swashbuckle) in .NET Core 6
-
Converting Enum Types By Value in C#
-
Implementing Microsoft.Extensions.Logging.ILogger with NLog
-
ASP.NET File Uploader with SignalR Progress Bar and Extended Input Stream Processing
-
How to inject Google Adsense In-Article script into your HTML (ASP.NET Core Razor)
-
Robust Error Handling in ASP.NET Core
-
A Utility Class for Finding Database Deadlocks in .NET Applications
-
Sanitizing HTML in .NET Core
-
Uploading Directly to S3 from Client Using Pre-Signed URLs (JavaScript, .NET)
-
Including Automated Swagger Documentation for API Dependencies
-
API Versioning and Basic UI Authentication with OpenAPI (Swagger / Swashbuckle) in .NET Core 6
-
Principles
-
JavaScript & TypeScript
-
AI
-
Software Architecture
-
General
-
Docker