diff --git a/lib/core/odp/odp_event_manager.ts b/lib/core/odp/odp_event_manager.ts index 80baa4822..3b91d7712 100644 --- a/lib/core/odp/odp_event_manager.ts +++ b/lib/core/odp/odp_event_manager.ts @@ -24,6 +24,7 @@ import { OdpConfig } from './odp_config'; import { IOdpEventApiManager } from './odp_event_api_manager'; import { invalidOdpDataFound } from './odp_utils'; import { IUserAgentParser } from './user_agent_parser'; +import { scheduleMicrotaskOrTimeout } from '../../utils/microtask'; const MAX_RETRIES = 3; @@ -393,14 +394,14 @@ export abstract class OdpEventManager implements IOdpEventManager { if (batch.length > 0) { // put sending the event on another event loop - queueMicrotask(async () => { + scheduleMicrotaskOrTimeout(async () => { let shouldRetry: boolean; let attemptNumber = 0; do { shouldRetry = await this.apiManager.sendEvents(odpConfig, batch); attemptNumber += 1; } while (shouldRetry && attemptNumber < this.retries); - }); + }) } } diff --git a/lib/core/project_config/project_config_manager.ts b/lib/core/project_config/project_config_manager.ts index 3f3aea4df..b0fe25ddd 100644 --- a/lib/core/project_config/project_config_manager.ts +++ b/lib/core/project_config/project_config_manager.ts @@ -20,6 +20,7 @@ import { ERROR_MESSAGES } from '../../utils/enums'; import { createOptimizelyConfig } from '../optimizely_config'; import { OnReadyResult, OptimizelyConfig, DatafileManager } from '../../shared_types'; import { ProjectConfig, toDatafile, tryCreatingProjectConfig } from '../project_config'; +import { scheduleMicrotaskOrTimeout } from '../../utils/microtask'; const logger = getLogger(); const MODULE_NAME = 'PROJECT_CONFIG_MANAGER'; @@ -189,10 +190,9 @@ export class ProjectConfigManager { if (configObj && oldRevision !== configObj.revision) { this.configObj = configObj; this.optimizelyConfigObj = null; - - queueMicrotask(() => { + scheduleMicrotaskOrTimeout(() => { this.updateListeners.forEach(listener => listener(configObj)); - }); + }) } } diff --git a/lib/utils/microtask/index.tests.js b/lib/utils/microtask/index.tests.js new file mode 100644 index 000000000..16091ad68 --- /dev/null +++ b/lib/utils/microtask/index.tests.js @@ -0,0 +1,38 @@ +/** + * Copyright 2024, Optimizely + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { scheduleMicrotaskOrTimeout } from './'; + +describe('scheduleMicrotaskOrTimeout', () => { + it('should use queueMicrotask if available', (done) => { + // Assuming queueMicrotask is available in the environment + scheduleMicrotaskOrTimeout(() => { + done(); + }); + }); + + it('should fallback to setTimeout if queueMicrotask is not available', (done) => { + // Temporarily remove queueMicrotask to test the fallback + const originalQueueMicrotask = window.queueMicrotask; + window.queueMicrotask = undefined; + + scheduleMicrotaskOrTimeout(() => { + // Restore queueMicrotask before calling done + window.queueMicrotask = originalQueueMicrotask; + done(); + }); + }); +}); diff --git a/lib/utils/microtask/index.ts b/lib/utils/microtask/index.ts new file mode 100644 index 000000000..816b17a27 --- /dev/null +++ b/lib/utils/microtask/index.ts @@ -0,0 +1,25 @@ +/** + * Copyright 2024, Optimizely + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type Callback = () => void; + +export const scheduleMicrotaskOrTimeout = (callback: Callback): void =>{ + if (typeof queueMicrotask === 'function') { + queueMicrotask(callback); + } else { + setTimeout(callback); + } +} \ No newline at end of file