Ben Carey
Ben Carey

Reputation: 16958

JavaScript Proxy: How to Empty Array Target

Consider the following JavaScript Proxy:

const queue = new Proxy([], {

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

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

        target[property] = value;

        this._processQueue();

        return true;

    }

});

The purpose of the above is to create a queue which is automatically processed whenever an item is added to it.

The problem is that once the queue is processed, I need to call flushQueue to remove the processed items. In other words, I need to empty the queue Proxy array.

Can anyone advise how to do this?

What I have tried...

// 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);

Update

Please see my full example here:

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);
    }
}

Upvotes: 0

Views: 1455

Answers (1)

Code Maniac
Code Maniac

Reputation: 37755

Problem in your code is you're calling this._processQueue before setting value to target, so it end-up in infinite loop, because it never set the value to target

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()

Upvotes: 1

Related Questions