JSFiddle - React, Tailwind, and code Playground

by Chen Huiting

HTML

<div id='test'>

  <button @click='click'>异步</button>
  <button @click='click1'>异步1</button> {{name}}<br/>

  <button @click='test'>同步</button> {{age}}
</div>

Babel + JSX

Vue.config.asyncErrorHandler = err => {
  console.log('catch async error:', err)
}

Vue.mixin({
  beforeCreate() {
    const methods = this.$options.methods || {}
    Object.keys(methods).forEach(key => {
      let fn = methods[key]
      this.$options.methods[key] = function(...args) {
        let ret = fn.apply(this, args);
        if (ret && typeof ret.catch === 'function') {
          return ret.catch(Vue.config.asyncErrorHandler)
        } else {
          return ret
        }
      }
    })
  },
})


new Vue({
  el: '#test',
  data: {
    name: "chen",
    age: 18
  },
  methods: {
    async click() {
      this.name = 'click'
      await timeout()
      console.log('正常运行,没有错误')
    },
    async click1() {
      this.name = 'click1'
      throw {msg:'async函数中同步抛错',status:1000}
    },
    test() {
      // 人为触发不捕获,
      // 生命周期中被Vue.config.errorHandler捕获
      throw {
        msg: '非async方法还是按照原来的方式处理错误',
        status: 3000
      }
      this.age = 20
    }
  },
  mounted(){
  	this.click1()
    this.test()
  }
})


// 模拟异步
function timeout() {
  return new Promise((resolve, reject) => {
    setTimeout(() => Math.random() > 0.5 ?
      resolve() :
      reject({
        msg: '随机的异步错误',
        status: 2000
      }), 500)
  })
}