Skip to content

Commit

Permalink
Return a promise in "once" if no listener provided (#10203)
Browse files Browse the repository at this point in the history
* return a promise in "once" if no listener provided

* fix ambiguity in map.once docs
  • Loading branch information
mourner authored Jan 11, 2021
1 parent 15f0983 commit bdfe181
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 12 deletions.
8 changes: 2 additions & 6 deletions debug/video-export.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@
easing: t => t
});
// wait for animation to finish
await untilMapEvent('moveend');
await map.once('moveend');
}

map.on('load', async () => {
map.addSource('dem', {type: 'raster-dem', url: 'mapbox://mapbox.mapbox-terrain-dem-v1'});
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;
Expand Down Expand Up @@ -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));
}

</script>
</body>
</html>
7 changes: 4 additions & 3 deletions src/ui/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/

/**
Expand Down
11 changes: 8 additions & 3 deletions src/util/evented.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<Event> {
if (!listener) {
return new Promise(resolve => this.once(type, resolve));
}

this._oneTimeListeners = this._oneTimeListeners || {};
_addEventListener(type, listener, this._oneTimeListeners);

Expand Down
6 changes: 6 additions & 0 deletions test/unit/util/evented.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down

0 comments on commit bdfe181

Please sign in to comment.