A lightweight library to supercharge the await operator!
Overwait takes your objects (and functions) and wraps them in a Proxy
that automatically distributes the await
operator down every step during property lookups, function return values, etc.
In practice, overwait transforms await a.b.c
into await (await (await a).b).c
.
overwait
is a single function. Simply pass it an object or a function and it'll return a Proxy
that wraps the original object and intercepts property accesses. For example:
import overwait from 'overwait';
// Wrap the fetch function to make it less tedious
const fetchy = overwait(fetch);
Here are some before and afters to give you an idea of the kind of code transformations that overwait
enables:
Before... | ...with Overwait! |
---|---|
const res = await fetch('https://x.com');
const body = await res.json(); |
const body = await fetchy('https://x.com').json(); |
// Not a specific db library, just an example
const conn = await db.conn('mydb');
const cursor = await conn.query('SELECT A');
const row = await cursor.getRow();
const value = await row.A; |
const value = await db.conn('mydb')
.query('SELECT A')
.getRow().A; |
const [fileHandle] = await showOpenFilePicker();
const file = await fileHandle.getFile(); |
const file = await showOpenFilePicker()[0].getFile(); |
When using overwait
to traverse a property chain, we automatically wrap the this
value in functions that are executed as a part of that traversal.
This fact allows you to write code like this:
const getValueFooBar = async function() {
// We don't need concern ourselves if
// `this`, `foo`, or `bar` are some mix of promises:
return await this.foo.bar;
};
Then when using that function in an object, it just works:
const obj = overwait({
foo: Promise.resolve({
bar: Promise.resolve('hi there!')
})
value: getValueFooBar
});
await obj.value(); //=> 'hi there!';
No await
? No problem!
Because await
is just syntactic sugar for then
, the way the library works actually allows you to then
to your hearts content.
What this means is that to overwait
this:
await promise1.promise2.promise3;
/*...stuff what comes after...*/
Is identical to this:
promise1.promise2.promise3.then(() => {
/*...stuff what comes after...*/
});
...and it just works!