@withdouble/babel-plugin-promisify-async-callback v0.2.0
@withdouble/babel-plugin-promisify-async-callback
Babel plugin to promisify callback-based functions with async notation at transpilation.
Why?
async
/await
feels great, promises not so much.- Wrapping everything in
return new Promise((resolve, reject) => { ... })
is utterly redundant (to write yourself). - Sometimes, there's nothing like a good ol'callback.
Install
Install as development dependency:
yarn add --dev @withdouble/babel-plugin-promisify-async-callback
Add this to your .babelrc file:
{
...
"plugins": [
"@withdouble/babel-plugin-promisify-async-callback"
...
]
}
Usage
Write "Error-First Callback" functions (because of the existing codebase, style preference, whatever), and use them either as "errback" functions or as returning a Promise.
- Mark the function as
async
- Name its last argument (the callback)
cb
You like/have callbacks...
Instead of writing
function fetchUser (userId, cb) {
api.getUser(userId, cb)
}
just add async
async function fetchUser (userId, cb) {
api.getUser(userId, cb)
}
and use with callbacks/promises/async/await.
...but want to get on the promise/async/await train?
Instead of writing this novel
function fetchUser (userId) {
return new Promise((resolve, reject) => {
api.getUser(userId, (error, user) => {
if (error) {
reject(error)
}
else {
resolve(user)
}
})
})
}
keep it simple
async function fetchUser (userId, cb) {
api.getUser(userId, cb)
}
and use with callbacks/promises/async/await.
So in the end
This function
async function fetchUser (userId, cb) {
api.getUser(userId, cb)
}
can be used with callbacks
fetchUser('jdoe', (error, user) => {
...
})
or promises
fetchUser('jdoe')
.then(user => { ... })
.catch(error => { ... })
or async/await
try {
const user = await fetchUser('jdoe')
}
catch (error) {
...
}
Gotchas :warning:
While you can use the function any way you want, you still have to write it as a callback-based function:
- Don’t
throw
any error, pass them through the callbackcb(error)
- Don’t
return
the result, pass it through the callbackcb(null, result)
- Don’t
await
What does it actually do?
It wraps the function body in return new Promise((resolve, reject) => { ... })
😄
and still calls cb
if one has been passed.
async function fetchUser (userId, cb) {
api.getUser(userId, cb)
}
transpiles to
async function fetchUser (userId, cb) {
const fn = cb => {
api.getUser(userId, cb)
}
return new Promise((resolve, reject) => {
fn(function(err, ...args) {
if (typeof cb === 'function') {
cb(err, ...args)
}
if (err) {
reject(err)
}
else {
resolve(...args)
}
})
})
}
(ok not exactly that, go check the code, it's pretty short)
6 years ago