Pull to refresh

Comments 13

Прокси — интересная штука. Но у вас какие-то дико искусственные примеры, по которым вообще не видно, как прокси облегчают жизнь.
Использовал прокси для создания базового класса модели, зависящей от нескольких источников информации. Очень упрощает реализацию дочерних классов.
Можете какой-то пример написать?
Получилась конструкция, которая работает наподобие git'a.

Есть this._map с данными, которые записываются при загрузке модели из разных источников и this._index, в котором хранятся все изменения (diff) модели от this._map

Естественно, остальные имплементации моделей уже расширяют данный класс.

Base.js
const VError = require('verror');

const { fromComponentsSchemas } = require('../utils/schemaExtractor');

const STATES = {
  UNDEFINED: 'UNDEFINED',
  CREATING: 'CREATING',
  LOADED: 'LOADED',
  DELETED: 'DELETED'
};

/**
 * Base class for our model structure, which takes the responsibility of getting and setting
 */
class ExtendableProxy {
  constructor() {
    return new Proxy(this, {
      set: (target, property, value, receiver) => {
        if (property.indexOf('_') !== 0) { // If not private property -> work with _index
          if (this._state === STATES.UNDEFINED) { // Transition to CREATING state
            this._state = STATES.CREATING;
          }

          if (!this._index[property] && this._map[property].value !== value) { // Check if not in index or not changed
            this._index[property] = Object.assign({}, this._map[property]);
            this._index[property].value = value;
          } else if (this._index[property]) { // If exists -> needs to be updated
            this._index[property].value = value;
          }

          return true;
        }

        target[property] = value;
        return true;
      },
      get: (target, property, receiver) => {
        // Check if not accessing the methods of the class
        // and not the private properties
        // and not symbol
        // so we could validate the state of a model
        if (typeof target[property] !== 'function' && typeof property !== 'symbol' && property.indexOf('_') !== 0) {
          if (this._state === STATES.UNDEFINED) throw new Error('Model is in UNDEFINED state');

          // TODO: Check if getter exists for this property and use it
          return (this._index[property] && this._index[property].value) || (this._map[property] && this._map[property].value);
        }

        return target[property];
      }
    });
  }
}

class Base extends ExtendableProxy {
  /**
   * Sets the source map for Model's variables
   */
  constructor(deviceId, modelName) {
    super();
    this._state = STATES.UNDEFINED;

    this._deviceId = deviceId;

    this._map = fromComponentsSchemas(modelName).properties;

    this._index = {}; // Index of model modifications

    if (!this._map) throw new VError(`Schema ${modelName} is not found`);
  }

  /**
   * Loads whole model from different sources, must be overrided
   * @return {Promise.<T>}
   */
  load() {
    this._state = STATES.LOADED;
  }

  /**
   * Sends the data from model to different sources, must be overrided
   * @return {Promise.<T>}
   */
  commit() {

  }

  /**
   * Deletes the model in different sources, must be overrided
   * @return {Promise.<T>}
   */
  delete() {
    this._state = STATES.DELETED;
  }

  /**
   * Returns an array of names of modified variables
   * @return {Array}
   */
  difference() {
    if (this._state === STATES.UNDEFINED) return [];

    const diff = [];

    for (let key in this._index) {
      diff.push(key);
    }

    return diff;
  }
}

Base.STATES = STATES;

module.exports = Base;

> Например, я полагаю, что должны появиться новые фреймворки, которые используют прокси в своей базовой функциональности.
Не знаю насчет новых, но Vue в 3-й версии, вроде бы, обещают переписать с использованием Proxy
Вообще не понял из статьи зачем нужна такая штука в реальной жизни
Явное лучше не явного,
api.getUsers() // magic
api.call('GET', 'users') // explicit
">
Очень интересно, что там у проксей с производительностью. Особенно когда одну в другую оборачивать и так далее.
UFO just landed and posted this here
Proxy отличная вещь, но от production ready его пока еще отделяет полное отсутствие поддержки в IE (11 всё еще актуален)
В свое время написал прокси сервис, который позволял делать любые апи запросы.

Как пример:
GET /users/1234/books?limit=10
POST /users/1234 {name: «User1»}
Выглядит так:
var response = await api.get.users(1234).books({limit:10})
var response = await api.post.users(1234)({name: "User1"})


Под капотом он обращался к апи, парсил ответ и генерировал ошибку если пошло что-то не так или возвращал ответ апи сервера
Другое (в комментариях)

Ещё вчера не использовал, но для сегодняшней задачки должно подойти как нельзя лучше.

Sign up to leave a comment.