You're likely already using await
with promises to receive values without creating a callback:
async function example(){
const data = await loadSomething()
// Use data for something...
}
But did you know you can use await
with objects other than promises?
The await
syntax can be used to wait for the completion of any thenable
(an object containing a then
function that takes a callback)! For example:
function wait(time){
return {then: done => setTimeout(done, time)}
}
async function example(){
console.log('Hello...') // Logs immediately
await wait(1000)
console.log('World!') // Logs after one second
}
This also means that instances of any class with a then
method can be used with await
:
class Wait {
constructor(time){
this.time = time
}
then(callback){
setTimeout(callback, this.time)
}
}
async function example(){
const delay = new Wait(1000)
console.log("Hello...")
await delay
console.log("World!")
}
Using thenables it's super easy to implement deferred and cancelable promises. This allows you to skip to the end of a promise or stop it from ever resolving at all!
class Deferred {
constructor(){
this.canceled = false
this.promise = new Promise((resolve, reject) => {
this.resolver = (value) => {
if(!this.canceled) resolve(value)
}
this.rejecter = (value) => {
if(!this.canceled) reject(value)
}
})
}
resolve(value){
this.resolver(value)
}
reject(value){
this.rejecter(value)
}
then(onFulfilled, onRejected){
this.promise.then(onFulfilled, onRejected)
}
cancel(){
this.canceled = true
}
}
Do you use thenables over promises anywhere in your codebase? Share your use cases in the comments!
Also, thanks for reading my first post!
Oldest comments (2)
Nice one! By the way, do you have an example of how to use it?
When I use then to return “this” with its callback it starts an infinite loop of calling then. I don't get why:
console:
With .then style it works perfectly: