try/catch
const fetchData = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('fetch data is me')},1000)})} (async() = > {try {
const data = await fetchData()
console.log('data is ->', data)
} catch(err) {
console.log('err is ->', err)
}
})()
Copy the code
Looks like it’s okay, but what if it is? There are multiple asynchronous operations, and the error status returned by each asynchronous operation needs to be handled differently. Here is sample code
const fetchDataA = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('fetch data is A')},1000)})}const fetchDataB = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('fetch data is B')},1000)})}const fetchDataC = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('fetch data is C')},1000)})} (async() = > {try {
const dataA = await fetchDataA()
console.log('dataA is ->', dataA)
} catch(err) {
console.log('err is ->', err)
}
try {
const dataB = await fetchDataB()
console.log('dataB is ->', dataB)
} catch(err) {
console.log('err is ->', err)
}
try {
const dataC = await fetchDataC()
console.log('dataC is ->', dataC)
} catch(err) {
console.log('err is ->', err)
}
})()
Copy the code
Are you comfortable with trying/catching code like this? It might be tempting to just use a try/catch.
/ /... Here the fetch function is omitted
(async() = > {try {
const dataA = await fetchDataA()
console.log('dataA is ->', dataA)
const dataB = await fetchDataB()
console.log('dataB is ->', dataB)
const dataC = await fetchDataC()
console.log('dataC is ->', dataC)
} catch(err) {
console.log('err is ->', err)
// Define err type and then decide?
/** * if (err.type === 'dataA') { * console.log('dataA err is', err) * } * ...... * * /
}
})()
Copy the code
“Async /await” is a promise syntax. “Promise” is a promise. “Then” is a promise
(async() = > {const fetchData = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('fetch data is me')},1000)})}const data = await fetchData().then(data= > data ).catch(err= > err)
console.log(data)
})()
Copy the code
FetchData (‘ resolve ‘, ‘reject’, ‘data’); fetchData (‘ resolve ‘, ‘reject’, ‘data’);
(async() = > {const fetchData = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('fetch data is me')},1000)})}const [err, data] = await fetchData().then(data= > [null, data] ).catch(err= > [err, null])
console.log('err', err)
console.log('data', data)
// err null
// data fetch data is me}) ()Copy the code
Isn’t that much better, but the problem is again, you can’t write every await so long, it’s not convenient and elegant to write, so optimize it
(async() = > {const fetchData = (a)= > {
return new Promise((resolve, reject) = > {
setTimeout((a)= > {
resolve('fetch data is me')},1000)})}// Extract into a public method
const awaitWrap = (promise) = > {
return promise
.then(data= > [null, data])
.catch(err= > [err, null])}const [err, data] = await awaitWrap(fetchData())
console.log('err', err)
console.log('data', data)
// err null
// data fetch data is me}) ()Copy the code
Isn’t it more elegant to call a method such as awaitWrap with await while separating the method from the public method to await it? This is what the typescript implementation would look like
function awaitWrap<T.U = any> (promise: Promise<T>) :Promise"[U | null.T | null] >{
return promise
.then<[null, T]>((data: T) = > [null, data]).catch"[U.null> (err => [err, null])}Copy the code
The above.