We can use something like this:
async function resolveToNumber () {
const promise = Promise.resolve(1)
const [error, result] = await to(promise)
console.log(error, result) // [null, 1] -> Here we have the result, and error will be null
}
async function resolveToString () {
const promise = Promise.resolve("a")
const [error, result] = await to(promise)
console.log(error, result) // [null, "a"] -> Here we have the result, and error will be null
}
async function resolveToObject () {
const promise = Promise.resolve({ a: 1, b: 2 })
const [error, result] = await to(promise)
console.log(error, result) // [null, { a: 1, b: 2 }] -> Here we have the result, and error will be null
}
async function rejected () {
const promise = Promise.reject(1)
const [error, result] = await to(promise)
console.log(error, result) // [Error, null] -> Here he have Error, and result will be null
}
In regular JavaScript, just create the function like this:
const to = p => p.then(r => [null, r]).catch(e => [e])
If you are using TypeScript, there are a few more ways to do the same thing.
First, we declare the possible return types:
type ErrorTuple = [Error, null]
type SuccessTuple <T> = [null, T]
Then, we can go this way:
async function to <T>(promise: Promise<T>) {
return promise
.then(r => [null, r] as SuccessTuple<T>)
.catch(e => [e, null] as ErrorTuple)
}
Or this way:
async function to <T>(promise: Promise<T>): Promise<ErrorTuple | SuccessTuple<T>> {
return promise
.then<SuccessTuple<T>>(r => [null, r])
.catch<ErrorTuple>(e => [e, null])
}
Or this way:
async function to <T>(promise: Promise<T>): Promise<ErrorTuple | SuccessTuple<T>> {
return promise
.then<SuccessTuple<T>, ErrorTuple>(
r => [null, r],
e => [e, null]
)
}
Or yet, this way:
async function to <T>(promise: Promise<T>): Promise<ErrorTuple | SuccessTuple<T>> {
try {
const result = await promise
return [null, result]
} catch (e) {
return [e, null]
}
}