diff --git a/debug/video-export.html b/debug/video-export.html index b21a32e7f58..473e422fee7 100644 --- a/debug/video-export.html +++ b/debug/video-export.html @@ -37,7 +37,7 @@ easing: t => t }); // wait for animation to finish - await untilMapEvent('moveend'); + await map.once('moveend'); } map.on('load', async () => { @@ -45,7 +45,7 @@ map.setTerrain({source: 'dem', exaggeration: 1.5}); // wait until the map settles - await untilMapEvent('idle'); + await map.once('idle'); // uncomment to fine-tune animation without recording: // animate(); return; @@ -102,10 +102,6 @@ // make sure to run `ffmpeg -i mapbox-gl.mp4 mapbox-gl-optimized.mp4` to compress the video }); -function untilMapEvent(type) { - return new Promise(resolve => map.once(type, resolve)); -} - diff --git a/src/ui/map.js b/src/ui/map.js index c7af6c4ec49..e9baad0c29b 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -1087,10 +1087,11 @@ class Map extends Camera { * @memberof Map * @instance * @param {string} type The event type to add a listener for. - * @param {Function} listener The function to be called when the event is fired. + * @param {Function} listener (optional) The function to be called when the event is fired once. * The listener function is called with the data object passed to `fire`, - * extended with `target` and `type` properties. - * @returns {Map} `this` + * extended with `target` and `type` properties. If the listener is not provided, + * returns a Promise that will be resolved when the event is fired once. + * @returns {Map} `this` | Promise */ /** diff --git a/src/util/evented.js b/src/util/evented.js index de05d109219..c29bffef346 100644 --- a/src/util/evented.js +++ b/src/util/evented.js @@ -90,10 +90,15 @@ export class Evented { * The listener will be called first time the event fires after the listener is registered. * * @param {string} type The event type to listen for. - * @param {Function} listener The function to be called when the event is fired the first time. - * @returns {Object} `this` + * @param {Function} listener (optional) The function to be called when the event is fired once. + * If not provided, returns a Promise that will be resolved when the event is fired once. + * @returns {Object} `this` | Promise */ - once(type: *, listener: Listener) { + once(type: *, listener?: Listener): this | Promise { + if (!listener) { + return new Promise(resolve => this.once(type, resolve)); + } + this._oneTimeListeners = this._oneTimeListeners || {}; _addEventListener(type, listener, this._oneTimeListeners); diff --git a/test/unit/util/evented.test.js b/test/unit/util/evented.test.js index eb1ed60b33f..ff6c6e97adb 100644 --- a/test/unit/util/evented.test.js +++ b/test/unit/util/evented.test.js @@ -24,6 +24,12 @@ test('Evented', (t) => { t.end(); }); + t.test('"once" returns a promise if no listener provided', (t) => { + const evented = new Evented(); + evented.once('a').then(() => t.end()); + evented.fire(new Event('a')); + }); + t.test('passes data to listeners', (t) => { const evented = new Evented(); evented.on('a', (data) => {