Skip to main content

once

Listen for the next matching event, then stop listening. This is addEventListener for one-shot cases, such as starting the next track when this one ends, or cleaning up after a fade.

once(type: SoundEventsEnum, callback: (event: SoundEvent) => void, filter?: SoundEventFilter): () => void;

Parameters​

ParameterTypeDefaultDescription
typeSoundEventsEnumrequiredThe event to wait for.
callback(event: SoundEvent) => voidrequiredCalled once, then removed.
filterSoundEventFilternoneNarrows which sounds count. See addEventListener for the fields.

Returns​

() => void: a function that cancels the listener before it has fired. Handy when a component unmounts while still waiting.

Example​

import { SoundHub, SoundEventsEnum } from 'soundhub';

const soundHub = new SoundHub();
await soundHub.loadSounds([
{ id: 'intro', url: '/audio/intro.mp3' },
{ id: 'music', url: '/audio/theme.mp3' },
]);

// Play the theme as soon as the intro is done, and only then
soundHub.once(SoundEventsEnum.ENDED, () => {
soundHub.play('music', { loop: true });
}, { soundId: 'intro' });

soundHub.play('intro');

Waiting for a fade​

soundHub.once(SoundEventsEnum.FADE_OUT_COMPLETED, () => {
soundHub.unloadSound('music');
}, { soundId: 'music' });

soundHub.fadeOut('music', 2);

Cancelling before it fires​

const cancel = soundHub.once(SoundEventsEnum.ENDED, playNext, { soundId: 'music' });

// The user skipped ahead, so the natural end no longer matters
cancel();

Good to know​

  • The listener is removed before your callback runs, so it cannot fire twice even if the callback triggers the same event again.
  • Doing this by hand means removing a listener from inside itself. Forget that and the listener keeps running for the rest of the session.
  • removeEventListener cannot remove a once listener with your callback, because the hub registers a wrapper around it. Use the returned function.

See also​