Dispatch events even when there are no listeners

Summary:
## Rationale
For every 1 call to RCTNetworking.sendRequest, we execute 6 calls to RCTNetworking.addListener. This is followed by at least one call to RCTNetworking.removeListeners. Aside from incrementing and decrementing the `_listeners` integer, these two methods accomplish nothing else: RCTNetworking doesn't implement the `startObserving` and `stopObserving` methods.

This diff makes RCTEventEmitter dispatch events without looking at the listeners integer. In the future, this will allow us to stop making these ~8 unnecessary NativeModule calls for every Network request we send.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D24272560

fbshipit-source-id: 7996eba5abfa4669a89c43a3ffa536c0faa214a8
This commit is contained in:
Ramanpreet Nara 2020-10-14 21:03:11 -07:00 коммит произвёл Facebook GitHub Bot
Родитель fb14fd42b3
Коммит 82187bfb6b
3 изменённых файлов: 28 добавлений и 3 удалений

Просмотреть файл

@ -159,7 +159,7 @@ RCT_EXPORT_MODULE()
- (instancetype)initWithHandlersProvider:(NSArray<id<RCTURLRequestHandler>> * (^)(void))getHandlers
{
if (self = [super init]) {
if (self = [super initWithDisabledObservation]) {
_handlersProvider = getHandlers;
}
return self;

Просмотреть файл

@ -16,6 +16,8 @@
@property (nonatomic, weak) RCTBridge *bridge;
- (instancetype)initWithDisabledObservation;
/**
* Override this method to return an array of supported event names. Attempting
* to observe or send an event that isn't included in this list will result in

Просмотреть файл

@ -12,6 +12,7 @@
@implementation RCTEventEmitter {
NSInteger _listenerCount;
BOOL _observationDisabled;
}
@synthesize invokeJS = _invokeJS;
@ -32,6 +33,13 @@
}
}
- (instancetype)initWithDisabledObservation
{
self = [super init];
_observationDisabled = YES;
return self;
}
- (NSArray<NSString *> *)supportedEvents
{
return nil;
@ -56,12 +64,15 @@
[self class],
[[self supportedEvents] componentsJoinedByString:@"`, `"]);
}
if (_listenerCount > 0 && _bridge) {
BOOL shouldEmitEvent = (_observationDisabled || _listenerCount > 0);
if (shouldEmitEvent && _bridge) {
[_bridge enqueueJSCall:@"RCTDeviceEventEmitter"
method:@"emit"
args:body ? @[ eventName, body ] : @[ eventName ]
completion:NULL];
} else if (_listenerCount > 0 && _invokeJS) {
} else if (shouldEmitEvent && _invokeJS) {
_invokeJS(@"RCTDeviceEventEmitter", @"emit", body ? @[ eventName, body ] : @[ eventName ]);
} else {
RCTLogWarn(@"Sending `%@` with no listeners registered.", eventName);
@ -80,6 +91,10 @@
- (void)invalidate
{
if (_observationDisabled) {
return;
}
if (_listenerCount > 0) {
[self stopObserving];
}
@ -87,6 +102,10 @@
RCT_EXPORT_METHOD(addListener : (NSString *)eventName)
{
if (_observationDisabled) {
return;
}
if (RCT_DEBUG && ![[self supportedEvents] containsObject:eventName]) {
RCTLogError(
@"`%@` is not a supported event type for %@. Supported events are: `%@`",
@ -102,6 +121,10 @@ RCT_EXPORT_METHOD(addListener : (NSString *)eventName)
RCT_EXPORT_METHOD(removeListeners : (double)count)
{
if (_observationDisabled) {
return;
}
int currentCount = (int)count;
if (RCT_DEBUG && currentCount > _listenerCount) {
RCTLogError(@"Attempted to remove more %@ listeners than added", [self class]);