async/await you can use it, but do you know how to deal with errors?

Posted by nileshn on Mon, 14 Feb 2022 03:44:44 +0100

preface

Hello, I'm Lin Sanxin. The most difficult knowledge point in the most easy to understand words is my motto. The foundation is advanced, and the premise is my original intention

Promise encapsulation request

If you usually use Promise to encapsulate the request, when you use this request function:

// Encapsulation request function
const request = (url, params) => {
  return new Promise((resolve, reject) => {
    // ...do something
  })
}

// When used
const handleLogin = () => {
  request(
    '/basic/login',
    {
      usename: 'sunshine',
      password: '123456'
    }
  ).then(res => {
    // success do something
  }).catch(err => {
    // fail do something
  })
}

You can see that when your request succeeds, you will call the then method, and when your request fails, you will call the catch method.

async/await

Promise solves many problems, but if there are too many requests and there are sequence requirements, it will inevitably lead to nesting and poor readability, such as:

const handleLogin = () => {
  request(
    '/basic/login',
    {
      usename: 'sunshine',
      password: '123456'
    }
  ).then(res => {
    // Obtain user information after successful login
    request(
      '/basic/getuserinfo',
      res.id
    ).then(info => {
      this.userInfo = info
    }).catch()
  }).catch(err => {
    // fail do something
  })

Therefore, async/await appears at this time. Its function is to perform asynchronous operations in a synchronous manner. If async/await is used, the above code can be rewritten as:

const handleLogin = async () => {
  const res = await request('/basic/login', {
    usename: 'sunshine',
    password: '123456'
  })
  const info = await request('/basic/getuserinfo', {
    id: res.id
  })
  this.userInfo = info
}

In this way, the readability of the code is relatively high without the nesting problem just now, but now there is another problem. Promise has a catch error callback to ensure what to do after the request error, but how should async/await catch the error?

async-to-js

In fact, there is already a library, async to JS, which has helped us do this. We can see how it does it. Its source code is only a dozen lines long. We should read its source code and learn its ideas

The source code is very simple

/**
 * @param { Promise } Request function passed in
 * @param { Object= } errorExt - Expand the wrong object
 * @return { Promise } Return a Promise
 */
export function to(
  promise,
  errorExt
) {
  return promise
    .then(data => [null, data])
    .catch(err => {
      if (errorExt) {
        const parsedError = Object.assign({}, err, errorExt)
        return [parsedError, undefined]
      }

      return [err, undefined]
    })
}

export default to

Summary of source code: the to function returns a Promise and the value is an array. There are two elements in the array. If the element with index 0 is not null, the request reports an error. If the element with index 0 is null, the request does not report an error, that is, it is successful.

It's easy to use

How do we use this to function? In fact, it's very simple. It's just an example

const handleLogin = async () => {
  const [resErr, res] = await to(request('/basic/login', {
    usename: 'sunshine',
    password: '123456'
  }))
  if (resErr) {
    // fail do somthing
    return
  }
  const [userErr, info] = await to(request('/basic/getuserinfo', {
    id: res.id
  }))
  if (userErr) {
    // fail do somthing
    return
  }
  this.userInfo = info
}

Therefore, you can still learn something by looking at the source code of some libraries occasionally!!!

epilogue

I'm Lin Sanxin, an enthusiastic front-end rookie programmer. If you are self-motivated, like the front-end and want to learn from the front-end, we can make friends and fish together. Ha ha, fish school, add me, please note [Si no]

Topics: Javascript Front-end ECMAScript