Question: I just can't figure out how to remove listener when I have some event executed. I have some leaking issue using websockets, and this can probaly fix it.

```
final WebSocket w = asyncHttpClient.prepareGet(url)
    .execute(new WebSocketUpgradeHandler.Builder().build())
    .get();

w.addWebSocketListener(new WebSocketTextListener() {

    public void onMessage(String message) {
        listener.onMessage(responseMessage);
        // Here is the place I want to do my w.removeWebSocketListener(l);
    }

    @Override
    public void onFragment(String s, boolean b) {
    }

    public void onOpen(WebSocket websocket) {
    }

    @Override
    public void onClose(WebSocket webSocket) {
    }

    @Override
    public void onError(Throwable throwable) {
    }

});

```

The problem is when I create `WebSocketTextListener lis = new ....` and passing in there is something like one object need other object and other object is dependent on this, and I'm still now allowed to do what I want.  

Looks like it is something simple, but can't figure out.

Answer: 
All JavaScript is single-threaded, synchronously executed. Any asynchronous stuff is done via events, which add their handlers to the task queue - to be executed when the current task is finished.

To use separate threads, you would need an environment like WebWorkers - every thread has its own execution context (global scope) and task queue; communication between them is done via events.

As the `onaudioprocess` handler seems to live in the same scope as the DOM, it is quite unlikely that it runs in its own thread. If you really have a computationally intensive task that makes your page unresponsive, you should use a WebWorker into which you feed the audio events:

```
myScriptProcessorNode.onaudioprocess = myWebWorker.postMessage;

```
With Bergi's solution, you're going to run into issues with the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) not being able to copy read only parameters in the audioProcessingEvent. What you need to do is break out the parts you need from the event that are cloneable, and pass them over to your worker in a different data structure like so:

```
_onAudioProcess(audioProcessingEvent) {
  const {inputBuffer, outputBuffer} = audioProcessingEvent;
  // The output buffer contains the samples that will be modified and
  // eventually played, so we need to keep a reference to it.
  this._outputBuffer = outputBuffer;
  const numChannels = inputBuffer.numberOfChannels;

  const inputChannels =
    Array.from({length: numChannels}, (i) => {
      return inputBuffer.getChannelData(i);
    });

  this._worker.postMessage({
    command: 'DO_STUFF',
    inputChannels: inputChannels,
  });
}

```

You're also going to need to access the reference to your outputBuffer in setMessageHandler, in order to copy the processed data back to be eventually played by the user.