javascript meta-programming of method_missing

javascript meta-programming of method_missing

introduction

Ruby metaprogramming to say too much in tips today to write this technology comes from the inspiration of ruby.

method_missing object calls this method if it will not be transferred to call this method in ruby.

How to achieve this function in javascript, now proxy there, there is this idea of.

achieve

class Base {
  constructor () {
    return new Proxy(this, {
      get (target, property) {
        if (Reflect.has(target, property)) {
          return Reflect.get(target, property)
        } else {
          return function () {
            if (target.method_missing) {
              return target.method_missing(property, ...arguments)
            } else {
              throw new ReferenceError('Property "' + property + '" does not exist.')
            }
          }
        }
      }
    })
  }
}

Code to explain, with the class, Proxy functionality.

How to use it?

I talk about scenarios, in the front end of a single page, there are a lot of ajax interfaces, how if you want to use under normal circumstances would do it?

Will first network library (jquery, axios) into sealing layer http, and then sub-layer requests into request, the final closure for each interface layer, the method becomes a method call, and into a folder management api, then referenced elsewhere.

Of course, this can work. The problem is that too redundant interface information, interface information in three places, url, the parameters, the method name, if there is to be a change, it may be three places must be changed.

And to have to do it again for each job function.

The following are examples:


// http 方法

import $ from 'jquery'

window.jQuery = $

$.ajaxSetup({
  cache: false,
  dataType: 'json'
})

// request 方法
export function request (url, setting) {
  return new Promise((resolve, reject) => {
    $.ajax(url, setting)
      .then(resolve)
      .fail(reject)
  })
}

export function get (url, params) {
  return request(url, {
    method: 'GET',
    data: params
  })
}

export function post (url, params) {
  return request(url, {
    method: 'POST',
    data: params
  })
}

// 具体的方法
import { post } from '@/lib/http'

export function getPermission (params = {}) {
  return post('/passport/permission', params)
}

We can see the specific method, the function name and url in fact express a meaning, but if I have to do it again interfaces.

If more than 20 interfaces, which are duplicate code, should not do it.

achieve

How to do it?

Written above method_missing method to play, and we do not seal method, the direct write function, and then commissioned method_missing unified method call, let us repeat freed from the seal method, dry something else.

import Base from './base'
import { request } from './http'
import * as _ from 'lodash'

let METHOD = {
  GET: ['get', 'show'],
  POST: ['post', 'update', 'change', 'create', 'delete', 'remove']
}

class ApiService extends Base {
  constructor () {
    super()
    this.baseURL = '/api/web'
  }

  method_missing (property, ...args) {
    let [url, setting] = args

    if (_.isObject(url)) {
      setting = {
        data: url
      }

      // 这里通过方法名生成 url
      const url_parts = property.split('_')
      const method = url_parts[0].toLowerCase()

      if (METHOD.GET.includes(method)) {
        setting.method = 'GET'
        url_parts.shift()
      } else if (METHOD.POST.includes(method)) {
        setting.method = 'POST'
        url_parts.shift()
      } else {
        setting.method = 'GET'
      }

      url = '/' + url_parts.join('/')
    }

    return request(this.baseURL + url, setting)
  }
}

export default new ApiService()


// 执行代码
import apiService from './api-service'

// 调用,神奇的代码
apiService.get_passport_permission({
})

From the point of view code execution, I do not define this method, which will fall apiserver in method_missing go.

Get the method name and parameter list, I was capable of things, with the name of the method according to the generated url, then add parameters, you can send a request.

in conclusion

This method on the code interfaces particularly if you are, you can save a lot of boilerplate code, but is more common code, the better, if there is a special case of code that can be added to achieve method_missing class.

Such common code and the code to take into account the special case, of course, compatibility is still to be considered.

Guess you like

Origin www.cnblogs.com/htoooth/p/11367829.html