I've run into similar issues and one of the things I've done is to check that this.element exists before operating on it.
Another thing I've done is to create a deferred property on the control. I resolve it when the async event has completed. I provide a function on the control called isReady() which returns the promise.
I use this pattern mostly so that when I have a control that performs some async actions during init, I can check when the control is done and ready. If and when other async events occur later on, I reset the deferred so that a call to isReady() basically says "it's not ready".
You could possibly do something like this in the destroy. Check isReady, which is really just checking if there is an async action occurring, and wait till there isn't to destroy it. So in your control's destroy, something like:
- destroy: function() {can.when( this.isReady() ).then(function() {// do your destroy stuffcan.Control.prototype.destroy.call(this);});}
Perhaps there's a better way to determine if the control is performing an async action, but I thought I throw this out there.
Often there is very little method to my madness...