From b76acd3f42ddff72f036dec608e0e44457b4c22b Mon Sep 17 00:00:00 2001 From: James Ide Date: Tue, 23 Apr 2019 02:46:34 -0700 Subject: [PATCH] Fix sparse array handling in `EventEmitter#listeners()` (#24546) Summary: Fixes a regression in https://github.com/facebook/react-native/commit/1f8b46a2fc191e2899735fbdcdbb535a91b63724. The internal subscription vendor uses a sparse array to track listeners, which makes listener removal fast. When querying listeners, the sparse entries need to be removed. `Array#filter` is a built-in way to do this -> linked to the JS spec, which explains this. [General] [Fixed] - Fixed sparse array handling in `EventEmitter#listeners()` Pull Request resolved: https://github.com/facebook/react-native/pull/24546 Differential Revision: D15044790 Pulled By: cpojer fbshipit-source-id: 0f1301618739357b4a0f5378b9584efe74f0f09a --- Libraries/vendor/emitter/EventEmitter.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Libraries/vendor/emitter/EventEmitter.js b/Libraries/vendor/emitter/EventEmitter.js index 28cf41afc889c3..bd9a7cc83da11a 100644 --- a/Libraries/vendor/emitter/EventEmitter.js +++ b/Libraries/vendor/emitter/EventEmitter.js @@ -16,6 +16,8 @@ const EventSubscriptionVendor = require('EventSubscriptionVendor'); const invariant = require('invariant'); +const sparseFilterPredicate = () => true; + /** * @class EventEmitter * @description @@ -151,7 +153,13 @@ class EventEmitter { listeners(eventType: string): [EmitterSubscription] { const subscriptions = this._subscriber.getSubscriptionsForType(eventType); return subscriptions - ? subscriptions.map(subscription => subscription.listener) + ? subscriptions + // We filter out missing entries because the array is sparse. + // "callbackfn is called only for elements of the array which actually + // exist; it is not called for missing elements of the array." + // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.filter + .filter(sparseFilterPredicate) + .map(subscription => subscription.listener) : []; }