Security News
Node.js EOL Versions CVE Dubbed the "Worst CVE of the Year" by Security Experts
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
babel-plugin-use-async
Advanced tools
Implements the "use async"
ECMAScript proposal.
Not intended for production use!
async
and await
are great but in practice the vast majority of async
function use await
and they are subject to the
What Color is Your Function
critique.
async
and await
were designed to minimize their effect on existing code
and specifications. While that is an entirely reasonable design goal it creates
the problem of not knowing whether a call to an async function without an
await
is intentional or accidental and the annoyance of having to litter your
code with await
statements.
"use async"
is an option, modeled on "use strict"
, that makes the following
changes to the language:
in async functions:
async
keyword can be used before an async function call
to indicate that it should not be await'dawait
works as beforein plain functions:
async
keyword before them
will throw an errorasync
keyword will throw an
errorawait
is invalid as beforeThe end result is a launguage where (almost) all code follows a traditional sequential control flow and the ambiguity about whether or not a function call should be await'd is eliminated.
Requiring async
to be used when calling async functions from plain functions
prevents a similar ambiguity from arising with regards to whether or not a
function was intended to be async
.
This proposal aims to resolve the issues raised by Proposal to add keyword "nowait" and async/await -> await/async: a simpler, less error-prone async syntax with the least amount of breakage and greatest amount of conceptual continuity.
async function getValueAsync() {
// get value from regular function that returns promise
const res = await http.get("/foo")
// return value
return res.val
}
function addOneSync(val) {
return val + 1
}
// seamlessly combine sync and async functions in an async function
async function bam() {
let y = getValueAsync() // 1
y = addOneSync(y) // 2
}
// use async functions from a regular function
function baz() {
let y = async getValueAsync() // <Promise>
y.then((y) => {
y = addOneSync(y) // 2
})
}
// calling async function without async is an unambiguous error
function bif() {
let y = getValueAsync() // Error!
}
This example demostrates how "use async"
eliminates the ambiguity with
await
by requiring the async
keyword to be used when calling
async functions from regular functions.
// SyntaxError on await
function getValueAsync() {
// get value from regular function that returns promise
const res = await http.get("/foo")
// return value
return res.val
}
// Error calling async function without async
function bam () {
let y = getValueAsync() // 1
y = addOneSync(y) // 2
}
With "use async"
mistakenly failing to declare a function as async
will
result in an error if that function either attempts to await
or attempts to
call another async function
.
// starts this, that and otherThing at same time, waits for results
async function collectResults() {
return Promise.all([
async this(),
async that(),
async otherThing()
])
}
// runs this, that and otherThing sequentially, then returns results
async function collectResults() {
return Promise.all([
this(),
that(),
otherThing()
])
}
Mistakenly omitting the async
keyword may result in incorrect execution but
will usually return correct results.
This is very different than mistakenly omitting an await
with standard
JavaScript, which will almost always yield incorrect results, sometimes in
obscure and unpredictable ways.
async function foo() {
let x = bar()
}
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor
async function foo() {
let x = (bar instanceof AsyncFunction ? await bar() : bar())
}
This does not work for code that does not use real async functions and it is not intended to.
The goal here is to reduce ambiguity about how code will behave at runtime so regular functions that return Promises should not be implicitly await'd.
$ node benchmark/async-function.js
Sync Function Calling Sync Function x 420,293,162 ops/sec ±0.07% (93 runs sampled)
Async Function Calling Sync Function x 105,306,976 ops/sec ±0.84% (92 runs sampled)
Await on Sync Function x 2,065,160 ops/sec ±5.59% (46 runs sampled)
Async Function with Explicit await x 2,114,176 ops/sec ±4.58% (51 runs sampled)
Async Function with Implicit await x 2,171,542 ops/sec ±3.06% (81 runs sampled)
The instanceof
call is so insignificant compared to the cost of await
that it
falls entirely within the range of normal test variation.
function foo() {
let x = bar()
}
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor
class AsyncError extends Error {
constructor(message) {
super(message || "async function called without async keyword")
}
}
function throwOnAsync(func) {
if (func instanceof AsyncFunction) throw new AsyncError()
return true
}
function foo() {
let x = (throwOnAsync(bar) && bar())
}
$ node benchmark/sync-function.js
Sync Function Calling Sync Function x 420,586,378 ops/sec ±0.07% (94 runs sampled)
Sync Function Calling Sync Function with Async Test x 66,005,927 ops/sec ±0.39% (85 runs sampled)
Sync Function Calling Sync Function with Async Test Node x 32,895,049 ops/sec ±0.57% (91 runs sampled)
Sync Function Calling Sync Function with Inline Async Test x 66,616,830 ops/sec ±0.53% (88 runs sampled)
Sync Function Calling Sync Function with Inline Async Test Node x 33,452,216 ops/sec ±0.21% (94 runs sampled)
Sync Function Calling Sync Function x 10000 x 107,901 ops/sec ±0.27% (95 runs sampled)
Sync Function Calling Sync Function with Async Test x 10000 x 23,968 ops/sec ±0.22% (97 runs sampled)
Sync Function Calling Sync Function x 10000 with 1 Async Test x 107,115 ops/sec ±0.22% (96 runs sampled)
Compared to a plain function call the instanceof
test does have a cost of 5-10X
which is pretty expensive, especially if it is in a tight loop.
For transpiling this can be addressed by hoisting the test outside of loops where
possible but this does not fix the case where a synchronous function with
"use async"
enabled is called in tight loop by another function.
Performance sensitive synchronous code that is likely to be run repeatedly should
avoid "use async"
until this can be resolved.
FAQs
Implements 'use async' ECMAScript proposal
The npm package babel-plugin-use-async receives a total of 2 weekly downloads. As such, babel-plugin-use-async popularity was classified as not popular.
We found that babel-plugin-use-async demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.