Fix listenToOnce memory leak

Builds off of @jmeas #3341, fixes #3226

We split out listenTo and listenToOnce from `once` to clean up any lingering listeners. Also adds some tests to check that `listenToOnce` works with maps.
`return this.listenTo(obj...)`?