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.