From a07c56c8fd293aa7ca68a00e36c3983237ed1996 Mon Sep 17 00:00:00 2001 From: Joshua Quick Date: Thu, 1 Apr 2021 18:45:59 -0700 Subject: [PATCH] refactor(ios): optimize promise creation on iOS 12 Fixes TIMOB-28412 --- .../TitaniumKit/Sources/Kroll/KrollPromise.m | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollPromise.m b/iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollPromise.m index a596abeccce..967fcc77244 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollPromise.m +++ b/iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollPromise.m @@ -32,21 +32,28 @@ - (KrollPromise *)initInContext:(JSContext *)context resolveFunc = [[JSValue valueWithJSValueRef:resolve inContext:context] retain]; rejectFunc = [[JSValue valueWithJSValueRef:reject inContext:context] retain]; } else { - // Alternative code for earlier versions of iOS. We hack it by evaluating JS - // TODO: I assume this is pretty slow. Can we re-use eval'd values here? - JSValue *executor = [context evaluateScript:@"function executor(resolve, reject) { executor.resolve = resolve; executor.reject = reject; }\nexecutor;"]; - JSValue *exception = context.exception; - if (exception != nil) { - [TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inJSContext:context]; + // For older iOS versions, create promise via below JS since there is no native API. + const NSString *JS_FUNCTION_NAME = @"_createKrollPromiseHandler"; + JSValue *createPromiseHandler = context[JS_FUNCTION_NAME]; + if (createPromiseHandler.isUndefined) { + [context evaluateScript:@"function _createKrollPromiseHandler() {" + " const handler = {};" + " handler.promise = new Promise((resolve, reject) => {" + " handler.resolve = resolve;" + " handler.reject = reject;" + " });" + " return handler;" + "}"]; + createPromiseHandler = context[JS_FUNCTION_NAME]; } - JSValue *createPromise = [context evaluateScript:@"function createPromise(executor) { return new Promise(executor); }\ncreatePromise;"]; - exception = context.exception; + JSValue *exception = context.exception; if (exception != nil) { [TiExceptionHandler.defaultExceptionHandler reportScriptError:exception inJSContext:context]; } - _JSValue = [[createPromise callWithArguments:@[ executor ]] retain]; - resolveFunc = [executor[@"resolve"] retain]; - rejectFunc = [executor[@"reject"] retain]; + JSValue *handler = [createPromiseHandler callWithArguments:nil]; + _JSValue = [handler[@"promise"] retain]; + resolveFunc = [handler[@"resolve"] retain]; + rejectFunc = [handler[@"reject"] retain]; } } return self;