Прокси JavaScript: как очистить целевой массив - PullRequest
0 голосов
/ 29 октября 2019

Рассмотрим следующий JavaScript Proxy:

const queue = new Proxy([], {

    get: (target, property) => {
        return target[property];
    },

    set: (target, property, value) => {

        target[property] = value;

        this._processQueue();

        return true;

    }

});

Цель вышеупомянутого состоит в создании queue, который автоматически обрабатывается при добавлении к нему элемента.

Проблема в том, что после обработки queue мне нужно позвонить flushQueue, чтобы удалить обработанные элементы. Другими словами, мне нужно очистить массив queue Proxy.

Может кто-нибудь посоветовать, как это сделать?

Что я пробовал ...

// Can't do this as a) queue is a constant, and b) it overrides the Proxy
queue = [];

// For some reason this doesn't work
queue.length = 0; 

// This empties the array but for some reason does not reset the length...
queue.splice(0, queue.length);

Обновление

Пожалуйста, смотрите мой полный пример здесь:

class Foo {

    /**
     * Foo constructor.
     *
     * @return void
     */
    constructor() {

        this.queue = new Proxy([], {

            get: (target, property) => {
                return target[property];
            },

            set: (target, property, value) => {

                this._processQueue();

                target[property] = value;

                return true;

            }

        });

    }

    /**
     * Add an event to the queue.
     *
     * @param {object} event
     * @return void
     */
    _addToQueue(event) {
        this.queue.push(event);
    }

    /**
     * Process the event queue.
     *
     * @return void
     */
    _processQueue() {

        console.log('process queue', this.queue, this.queue.length);

        if (this.queue.length) {

            this.queue.forEach((event, index) => {

                console.log(event);

                const method = this._resolveEvent(event.type);

                const payload = typeof event.payload !== 'undefined' ? event.payload : {};

                //this[method](payload);

            });

            this._flushQueue();

        }

    }

    /**
     * Flush the event queue.
     *
     * @return void
     */
    _flushQueue() {
        this.queue.splice(0, this.queue.length);
    }
}

1 Ответ

1 голос
/ 29 октября 2019

Проблема в вашем коде заключается в том, что вы вызываете this._processQueue перед тем, как установить значение для цели, поэтому оно заканчивается бесконечным циклом, потому что никогда не устанавливает значение для цели

class Foo {
  constructor() {
    this.queue = new Proxy([], {
      get: (target, property) => {
        return target[property];
      },
      set: (target, property, value) => {
        console.log('set called', value)
        target[property] = value;
        this._processQueue();
        return true;
      }
    });
  }

  _addToQueue(event) {
    this.queue.push(event);
  }

  _processQueue() {
    console.log('process queue', this.queue, this.queue.length);
    if (this.queue.length) {
      this.queue.forEach((event, index) => {
        console.log(event);
        //                 const method = this._resolveEvent(event.type);
        const payload = typeof event.payload !== 'undefined' ? event.payload : {};
        //this[method](payload);
      });
      this._flushQueue();
    }
  }

  _flushQueue() {
    this.queue.splice(0, this.queue.length);
  }
}

const q = new Foo()
q._addToQueue({
  type: 'clcik',
  payload: 'hello'
})
q._processQueue()
...