MOBILE-3988 core: Remove duplicated promise helper

main
Noel De Martin 2022-05-30 18:13:43 +02:00
parent b67d27fc0e
commit 6356623664
25 changed files with 162 additions and 201 deletions

View File

@ -321,17 +321,8 @@ export class AddonFilterMathJaxLoaderHandlerService extends CoreFilterDefaultHan
return; return;
} }
const deferred = CoreUtils.promiseDefer<void>(); await CoreUtils.wait(250);
await CoreUtils.ignoreErrors(this.waitForReady(retries + 1));
setTimeout(async () => {
try {
await this.waitForReady(retries + 1);
} finally {
deferred.resolve();
}
}, 250);
return deferred.promise;
} }
/** /**

View File

@ -888,18 +888,13 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
* *
* @return Resolved when done. * @return Resolved when done.
*/ */
protected waitForFetch(): Promise<void> { protected async waitForFetch(): Promise<void> {
if (!this.fetching) { if (!this.fetching) {
return Promise.resolve(); return;
} }
const deferred = CoreUtils.promiseDefer<void>(); await CoreUtils.wait(400);
await CoreUtils.ignoreErrors(this.waitForFetch());
setTimeout(() => this.waitForFetch().finally(() => {
deferred.resolve();
}), 400);
return deferred.promise;
} }
/** /**

View File

@ -15,8 +15,8 @@
import { BehaviorSubject, Subject } from 'rxjs'; import { BehaviorSubject, Subject } from 'rxjs';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreDelegate, CoreDelegateDisplayHandler, CoreDelegateToDisplay } from './delegate'; import { CoreDelegate, CoreDelegateDisplayHandler, CoreDelegateToDisplay } from './delegate';
import { CoreUtils } from '@services/utils/utils';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Superclass to help creating sorted delegates. * Superclass to help creating sorted delegates.
@ -96,18 +96,17 @@ export class CoreSortedDelegate<
return this.sortedHandlers; return this.sortedHandlers;
} }
const deferred = CoreUtils.promiseDefer<DisplayType[]>(); const promisedHandlers = new CorePromisedValue<DisplayType[]>();
const subscription = this.getHandlersObservable().subscribe((handlers) => { const subscription = this.getHandlersObservable().subscribe((handlers) => {
if (this.loaded) { if (this.loaded) {
subscription?.unsubscribe(); subscription?.unsubscribe();
// Return main handlers. // Return main handlers.
deferred.resolve(handlers); promisedHandlers.resolve(handlers);
} }
}); });
return deferred.promise; return promisedHandlers;
} }
/** /**

View File

@ -55,6 +55,13 @@ export class CorePromisedValue<T = unknown> extends CorePromise<T> {
this.rejectPromise = rejectPromise; this.rejectPromise = rejectPromise;
} }
/**
* @deprecated since app 4.1. The instance can be directly used as a promise.
*/
get promise(): Promise<T> {
return this;
}
get value(): T | null { get value(): T | null {
return this.resolvedValue ?? null; return this.resolvedValue ?? null;
} }

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CoreUtils, PromiseDefer } from '@services/utils/utils'; import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Function to add to the queue. * Function to add to the queue.
@ -38,7 +38,7 @@ export type CoreQueueRunnerItem<T = any> = {
/** /**
* Deferred with a promise resolved/rejected with the result of the function. * Deferred with a promise resolved/rejected with the result of the function.
*/ */
deferred: PromiseDefer<T>; deferred: CorePromisedValue<T>;
}; };
/** /**
@ -122,7 +122,7 @@ export class CoreQueueRunner {
if (id in this.queue) { if (id in this.queue) {
if (!options.allowRepeated) { if (!options.allowRepeated) {
// Item already in queue, return its promise. // Item already in queue, return its promise.
return this.queue[id].deferred.promise; return this.queue[id].deferred;
} }
id = this.getUniqueId(id); id = this.getUniqueId(id);
@ -132,7 +132,7 @@ export class CoreQueueRunner {
const item = { const item = {
id, id,
fn, fn,
deferred: CoreUtils.promiseDefer<T>(), deferred: new CorePromisedValue<T>(),
}; };
this.queue[id] = item; this.queue[id] = item;
@ -141,7 +141,7 @@ export class CoreQueueRunner {
// Process next item if we haven't reached the max yet. // Process next item if we haven't reached the max yet.
this.processNextItem(); this.processNextItem();
return item.deferred.promise; return item.deferred;
} }
} }

View File

@ -32,7 +32,7 @@ import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUrlUtils, CoreUrlParams } from '@services/utils/url'; import { CoreUrlUtils, CoreUrlParams } from '@services/utils/url';
import { CoreUtils, CoreUtilsOpenInBrowserOptions, PromiseDefer } from '@services/utils/utils'; import { CoreUtils, CoreUtilsOpenInBrowserOptions } from '@services/utils/utils';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { SQLiteDB } from '@classes/sqlitedb'; import { SQLiteDB } from '@classes/sqlitedb';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
@ -46,6 +46,7 @@ import { asyncInstance, AsyncInstance } from '../utils/async-instance';
import { CoreDatabaseTable } from './database/database-table'; import { CoreDatabaseTable } from './database/database-table';
import { CoreDatabaseCachingStrategy } from './database/database-table-proxy'; import { CoreDatabaseCachingStrategy } from './database/database-table-proxy';
import { CoreSilentError } from './errors/silenterror'; import { CoreSilentError } from './errors/silenterror';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* QR Code type enumeration. * QR Code type enumeration.
@ -779,7 +780,7 @@ export class CoreSite {
if (preSets.reusePending) { if (preSets.reusePending) {
const request = this.requestQueue.find((request) => request.cacheId == cacheId); const request = this.requestQueue.find((request) => request.cacheId == cacheId);
if (request) { if (request) {
return request.deferred.promise; return request.deferred;
} }
} }
@ -789,7 +790,7 @@ export class CoreSite {
data, data,
preSets, preSets,
wsPreSets, wsPreSets,
deferred: CoreUtils.promiseDefer(), deferred: new CorePromisedValue(),
}; };
return this.enqueueRequest(request); return this.enqueueRequest(request);
@ -813,7 +814,7 @@ export class CoreSite {
); );
} }
return request.deferred.promise; return request.deferred;
} }
/** /**
@ -2291,7 +2292,7 @@ type RequestQueueItem<T = any> = {
data: any; // eslint-disable-line @typescript-eslint/no-explicit-any data: any; // eslint-disable-line @typescript-eslint/no-explicit-any
preSets: CoreSiteWSPreSets; preSets: CoreSiteWSPreSets;
wsPreSets: CoreWSPreSets; wsPreSets: CoreWSPreSets;
deferred: PromiseDefer<T>; deferred: CorePromisedValue<T>;
}; };
/** /**

View File

@ -33,6 +33,7 @@ import {
Type, Type,
KeyValueDiffer, KeyValueDiffer,
} from '@angular/core'; } from '@angular/core';
import { CorePromisedValue } from '@classes/promised-value';
import { CoreCompile } from '@features/compile/services/compile'; import { CoreCompile } from '@features/compile/services/compile';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
@ -278,14 +279,14 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck {
return this.pendingCalls[name].defer.promise; return this.pendingCalls[name].defer.promise;
} }
const defer = CoreUtils.promiseDefer(); const defer = new CorePromisedValue();
this.pendingCalls[name] = { this.pendingCalls[name] = {
params, params,
defer, defer,
}; };
return defer.promise; return defer;
} }
} }

View File

@ -154,6 +154,7 @@ import { ADDON_PRIVATEFILES_SERVICES } from '@addons/privatefiles/privatefiles.m
// Import some addon modules that define components, directives and pipes. Only import the important ones. // Import some addon modules that define components, directives and pipes. Only import the important ones.
import { AddonModAssignComponentsModule } from '@addons/mod/assign/components/components.module'; import { AddonModAssignComponentsModule } from '@addons/mod/assign/components/components.module';
import { AddonModWorkshopComponentsModule } from '@addons/mod/workshop/components/components.module'; import { AddonModWorkshopComponentsModule } from '@addons/mod/workshop/components/components.module';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Service to provide functionalities regarding compiling dynamic HTML and Javascript. * Service to provide functionalities regarding compiling dynamic HTML and Javascript.
@ -352,6 +353,7 @@ export class CoreCompileProvider {
instance['CoreWindow'] = CoreWindow; instance['CoreWindow'] = CoreWindow;
instance['CoreCache'] = CoreCache; instance['CoreCache'] = CoreCache;
instance['CoreDelegate'] = CoreDelegate; instance['CoreDelegate'] = CoreDelegate;
instance['CorePromisedValue'] = CorePromisedValue;
instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase; instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase;
instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler; instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler;
instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler; instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler;

View File

@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
import { CoreDelegate, CoreDelegateHandler, CoreDelegateToDisplay } from '@classes/delegate'; import { CoreDelegate, CoreDelegateHandler, CoreDelegateToDisplay } from '@classes/delegate';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreUtils, PromiseDefer } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { import {
CoreCourseAnyCourseData, CoreCourseAnyCourseData,
CoreCourseAnyCourseDataWithOptions, CoreCourseAnyCourseDataWithOptions,
@ -28,6 +28,7 @@ import { CoreCourseProvider } from './course';
import { Params } from '@angular/router'; import { Params } from '@angular/router';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreEnrolledCourseDataWithExtraInfoAndOptions } from '@features/courses/services/courses-helper'; import { CoreEnrolledCourseDataWithExtraInfoAndOptions } from '@features/courses/services/courses-helper';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Interface that all course options handlers must implement. * Interface that all course options handlers must implement.
@ -224,7 +225,7 @@ export class CoreCourseOptionsDelegateService extends CoreDelegate<CoreCourseOpt
access: CoreCourseAccess; access: CoreCourseAccess;
navOptions?: CoreCourseUserAdminOrNavOptionIndexed; navOptions?: CoreCourseUserAdminOrNavOptionIndexed;
admOptions?: CoreCourseUserAdminOrNavOptionIndexed; admOptions?: CoreCourseUserAdminOrNavOptionIndexed;
deferred: PromiseDefer<void>; deferred: CorePromisedValue<void>;
enabledHandlers: CoreCourseOptionsHandler[]; enabledHandlers: CoreCourseOptionsHandler[];
enabledMenuHandlers: CoreCourseOptionsMenuHandler[]; enabledMenuHandlers: CoreCourseOptionsMenuHandler[];
}; };
@ -331,7 +332,7 @@ export class CoreCourseOptionsDelegateService extends CoreDelegate<CoreCourseOpt
access: accessData, access: accessData,
navOptions, navOptions,
admOptions, admOptions,
deferred: CoreUtils.promiseDefer(), deferred: new CorePromisedValue(),
enabledHandlers: [], enabledHandlers: [],
enabledMenuHandlers: [], enabledMenuHandlers: [],
}; };
@ -339,13 +340,13 @@ export class CoreCourseOptionsDelegateService extends CoreDelegate<CoreCourseOpt
this.coursesHandlers[courseId].access = accessData; this.coursesHandlers[courseId].access = accessData;
this.coursesHandlers[courseId].navOptions = navOptions; this.coursesHandlers[courseId].navOptions = navOptions;
this.coursesHandlers[courseId].admOptions = admOptions; this.coursesHandlers[courseId].admOptions = admOptions;
this.coursesHandlers[courseId].deferred = CoreUtils.promiseDefer(); this.coursesHandlers[courseId].deferred = new CorePromisedValue();
} }
this.updateHandlersForCourse(courseId, accessData, navOptions, admOptions); this.updateHandlersForCourse(courseId, accessData, navOptions, admOptions);
} }
await this.coursesHandlers[courseId].deferred.promise; await this.coursesHandlers[courseId].deferred;
return this.coursesHandlers[courseId].enabledHandlers; return this.coursesHandlers[courseId].enabledHandlers;
} }

View File

@ -1304,16 +1304,15 @@ export class CoreCourseProvider {
} }
// Wait for plugins to be loaded. // Wait for plugins to be loaded.
const deferred = CoreUtils.promiseDefer<void>(); await new Promise((resolve, reject) => {
const observer = CoreEvents.on(CoreEvents.SITE_PLUGINS_LOADED, () => {
observer?.off();
const observer = CoreEvents.on(CoreEvents.SITE_PLUGINS_LOADED, () => { CoreCourseFormatDelegate.openCourse(<CoreCourseAnyCourseData> course, navOptions).then(resolve).catch(reject);
observer?.off(); });
CoreCourseFormatDelegate.openCourse(<CoreCourseAnyCourseData> course, navOptions)
.then(deferred.resolve).catch(deferred.reject);
}); });
return deferred.promise; return;
} catch (error) { } catch (error) {
// The site plugin failed to load. The user needs to restart the app to try loading it again. // The site plugin failed to load. The user needs to restart the app to try loading it again.
const message = Translate.instant('core.courses.errorloadplugins'); const message = Translate.instant('core.courses.errorloadplugins');

View File

@ -24,7 +24,7 @@ import { CoreFile, CoreFileProvider, CoreFileProgressEvent } from '@services/fil
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreUtils, PromiseDefer } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { makeSingleton, Translate, Camera, Chooser, Platform, ActionSheetController } from '@singletons'; import { makeSingleton, Translate, Camera, Chooser, Platform, ActionSheetController } from '@singletons';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreCanceledError } from '@classes/errors/cancelederror'; import { CoreCanceledError } from '@classes/errors/cancelederror';
@ -36,6 +36,7 @@ import { CoreIonLoadingElement } from '@classes/ion-loading';
import { CoreWSUploadFileResult } from '@services/ws'; import { CoreWSUploadFileResult } from '@services/ws';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Helper service to upload files. * Helper service to upload files.
@ -44,7 +45,7 @@ import { CoreText } from '@singletons/text';
export class CoreFileUploaderHelperProvider { export class CoreFileUploaderHelperProvider {
protected logger: CoreLogger; protected logger: CoreLogger;
protected filePickerDeferred?: PromiseDefer<CoreWSUploadFileResult | FileEntry>; protected filePickerDeferred?: CorePromisedValue<CoreWSUploadFileResult | FileEntry>;
protected actionSheet?: HTMLIonActionSheetElement; protected actionSheet?: HTMLIonActionSheetElement;
constructor() { constructor() {
@ -349,7 +350,7 @@ export class CoreFileUploaderHelperProvider {
}]; }];
const handlers = CoreFileUploaderDelegate.getHandlers(mimetypes); const handlers = CoreFileUploaderDelegate.getHandlers(mimetypes);
this.filePickerDeferred = CoreUtils.promiseDefer(); this.filePickerDeferred = new CorePromisedValue();
// Create a button for each handler. // Create a button for each handler.
handlers.forEach((handler) => { handlers.forEach((handler) => {
@ -431,7 +432,7 @@ export class CoreFileUploaderHelperProvider {
}); });
}, 500); }, 500);
return this.filePickerDeferred.promise; return this.filePickerDeferred;
} }
/** /**

View File

@ -1288,34 +1288,27 @@ export class CoreLoginHelperProvider {
* *
* @return Promise resolved if the user accepts to scan QR. * @return Promise resolved if the user accepts to scan QR.
*/ */
showScanQRInstructions(): Promise<void> { async showScanQRInstructions(): Promise<void> {
const deferred = CoreUtils.promiseDefer<void>(); await new Promise<void>((resolve, reject) => {
CoreDomUtils.showAlertWithOptions({
// Show some instructions first. header: Translate.instant('core.login.faqwhereisqrcode'),
CoreDomUtils.showAlertWithOptions({ message: Translate.instant(
header: Translate.instant('core.login.faqwhereisqrcode'), 'core.login.faqwhereisqrcodeanswer',
message: Translate.instant( { $image: CoreLoginHelperProvider.FAQ_QRCODE_IMAGE_HTML },
'core.login.faqwhereisqrcodeanswer', ),
{ $image: CoreLoginHelperProvider.FAQ_QRCODE_IMAGE_HTML }, buttons: [
), {
buttons: [ text: Translate.instant('core.cancel'),
{ role: 'cancel',
text: Translate.instant('core.cancel'), handler: () => reject(new CoreCanceledError()),
role: 'cancel',
handler: (): void => {
deferred.reject(new CoreCanceledError());
}, },
}, {
{ text: Translate.instant('core.next'),
text: Translate.instant('core.next'), handler: () => resolve(),
handler: (): void => {
deferred.resolve();
}, },
}, ],
], });
}); });
return deferred.promise;
} }
/** /**

View File

@ -256,14 +256,13 @@ export class CorePushNotificationsProvider {
return; return;
} }
const deferred = CoreUtils.promiseDefer<void>(); await new Promise<void>(resolve => {
win.PushNotification.enableAnalytics(resolve, (error) => {
this.logger.error('Error enabling or disabling Firebase analytics', enable, error);
win.PushNotification.enableAnalytics(deferred.resolve, (error) => { resolve();
this.logger.error('Error enabling or disabling Firebase analytics', enable, error); }, !!enable);
deferred.resolve(); });
}, !!enable);
await deferred.promise;
} }
/** /**
@ -357,14 +356,12 @@ export class CorePushNotificationsProvider {
return; return;
} }
const deferred = CoreUtils.promiseDefer<void>(); await new Promise<void>(resolve => {
win.PushNotification.logEvent(resolve, (error) => {
win.PushNotification.logEvent(deferred.resolve, (error) => { this.logger.error('Error logging firebase event', name, error);
this.logger.error('Error logging firebase event', name, error); resolve();
deferred.resolve(); }, name, data, !!filter);
}, name, data, !!filter); });
await deferred.promise;
} }
/** /**

View File

@ -27,8 +27,8 @@ import {
CoreSitePluginsCourseOptionHandlerData, CoreSitePluginsCourseOptionHandlerData,
CoreSitePluginsPlugin, CoreSitePluginsPlugin,
} from '@features/siteplugins/services/siteplugins'; } from '@features/siteplugins/services/siteplugins';
import { CoreUtils, PromiseDefer } from '@services/utils/utils';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Handler to display a site plugin in course options. * Handler to display a site plugin in course options.
@ -38,7 +38,7 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl
priority: number; priority: number;
isMenuHandler: boolean; isMenuHandler: boolean;
protected updatingDefer?: PromiseDefer<void>; protected updatingDefer?: CorePromisedValue<void>;
constructor( constructor(
name: string, name: string,
@ -59,7 +59,7 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl
async isEnabledForCourse(courseId: number): Promise<boolean> { async isEnabledForCourse(courseId: number): Promise<boolean> {
// Wait for "init" result to be updated. // Wait for "init" result to be updated.
if (this.updatingDefer) { if (this.updatingDefer) {
await this.updatingDefer.promise; await this.updatingDefer;
} }
return CoreSitePlugins.isHandlerEnabledForCourse( return CoreSitePlugins.isHandlerEnabledForCourse(
@ -132,7 +132,7 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl
* Mark init being updated. * Mark init being updated.
*/ */
updatingInit(): void { updatingInit(): void {
this.updatingDefer = CoreUtils.promiseDefer(); this.updatingDefer = new CorePromisedValue();
} }
} }

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CorePromisedValue } from '@classes/promised-value';
import { import {
CoreSitePlugins, CoreSitePlugins,
CoreSitePluginsContent, CoreSitePluginsContent,
@ -26,7 +27,6 @@ import {
CoreUserProfileHandlerData, CoreUserProfileHandlerData,
} from '@features/user/services/user-delegate'; } from '@features/user/services/user-delegate';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreUtils, PromiseDefer } from '@services/utils/utils';
import { Md5 } from 'ts-md5'; import { Md5 } from 'ts-md5';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
@ -38,7 +38,7 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle
priority: number; priority: number;
type: string; type: string;
protected updatingDefer?: PromiseDefer<void>; protected updatingDefer?: CorePromisedValue<void>;
constructor( constructor(
name: string, name: string,
@ -130,7 +130,7 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle
* Mark init being updated. * Mark init being updated.
*/ */
updatingInit(): void { updatingInit(): void {
this.updatingDefer = CoreUtils.promiseDefer(); this.updatingDefer = new CorePromisedValue();
} }
} }

View File

@ -23,12 +23,13 @@ import { CoreFilepool } from '@services/filepool';
import { CoreLang } from '@services/lang'; import { CoreLang } from '@services/lang';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreUtils, PromiseDefer } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws'; import { CoreWSExternalFile, CoreWSExternalWarning } from '@services/ws';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreSitePluginsModuleHandler } from '../classes/handlers/module-handler'; import { CoreSitePluginsModuleHandler } from '../classes/handlers/module-handler';
import { CorePromisedValue } from '@classes/promised-value';
const ROOT_CACHE_KEY = 'CoreSitePlugins:'; const ROOT_CACHE_KEY = 'CoreSitePlugins:';
@ -44,7 +45,7 @@ export class CoreSitePluginsProvider {
protected logger: CoreLogger; protected logger: CoreLogger;
protected sitePlugins: {[name: string]: CoreSitePluginsHandler} = {}; // Site plugins registered. protected sitePlugins: {[name: string]: CoreSitePluginsHandler} = {}; // Site plugins registered.
protected sitePluginPromises: {[name: string]: Promise<void>} = {}; // Promises of loading plugins. protected sitePluginPromises: {[name: string]: Promise<void>} = {}; // Promises of loading plugins.
protected fetchPluginsDeferred: PromiseDefer<void>; protected fetchPluginsDeferred: CorePromisedValue<void>;
protected moduleHandlerInstances: Record<string, CoreSitePluginsModuleHandler> = {}; protected moduleHandlerInstances: Record<string, CoreSitePluginsModuleHandler> = {};
hasSitePluginsLoaded = false; hasSitePluginsLoaded = false;
@ -59,9 +60,9 @@ export class CoreSitePluginsProvider {
}); });
// Initialize deferred at start and on logout. // Initialize deferred at start and on logout.
this.fetchPluginsDeferred = CoreUtils.promiseDefer(); this.fetchPluginsDeferred = new CorePromisedValue();
CoreEvents.on(CoreEvents.LOGOUT, () => { CoreEvents.on(CoreEvents.LOGOUT, () => {
this.fetchPluginsDeferred = CoreUtils.promiseDefer(); this.fetchPluginsDeferred = new CorePromisedValue();
}); });
} }
@ -659,8 +660,8 @@ export class CoreSitePluginsProvider {
* *
* @return Promise resolved when site plugins have been fetched. * @return Promise resolved when site plugins have been fetched.
*/ */
waitFetchPlugins(): Promise<void> { async waitFetchPlugins(): Promise<void> {
return this.fetchPluginsDeferred.promise; await this.fetchPluginsDeferred;
} }
/** /**

View File

@ -16,7 +16,6 @@ import { Injectable } from '@angular/core';
import { CoreDB } from '@services/db'; import { CoreDB } from '@services/db';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreUtils, PromiseDefer } from '@services/utils/utils';
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
import { makeSingleton, Keyboard, Network, StatusBar, Platform, Device } from '@singletons'; import { makeSingleton, Keyboard, Network, StatusBar, Platform, Device } from '@singletons';
@ -28,6 +27,8 @@ import { CoreRedirectPayload } from './navigator';
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy'; import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
import { asyncInstance } from '../utils/async-instance'; import { asyncInstance } from '../utils/async-instance';
import { CoreDatabaseTable } from '@classes/database/database-table'; import { CoreDatabaseTable } from '@classes/database/database-table';
import { CorePromisedValue } from '@classes/promised-value';
import { Subscription } from 'rxjs';
/** /**
* Factory to provide some global functionalities, like access to the global app database. * Factory to provide some global functionalities, like access to the global app database.
@ -47,7 +48,7 @@ export class CoreAppProvider {
protected db?: SQLiteDB; protected db?: SQLiteDB;
protected logger: CoreLogger; protected logger: CoreLogger;
protected ssoAuthenticationDeferred?: PromiseDefer<void>; protected ssoAuthenticationDeferred?: CorePromisedValue<void>;
protected isKeyboardShown = false; protected isKeyboardShown = false;
protected keyboardOpening = false; protected keyboardOpening = false;
protected keyboardClosing = false; protected keyboardClosing = false;
@ -451,14 +452,14 @@ export class CoreAppProvider {
* NOT when the browser is opened. * NOT when the browser is opened.
*/ */
startSSOAuthentication(): void { startSSOAuthentication(): void {
this.ssoAuthenticationDeferred = CoreUtils.promiseDefer<void>(); this.ssoAuthenticationDeferred = new CorePromisedValue();
// Resolve it automatically after 10 seconds (it should never take that long). // Resolve it automatically after 10 seconds (it should never take that long).
const cancelTimeout = setTimeout(() => this.finishSSOAuthentication(), 10000); const cancelTimeout = setTimeout(() => this.finishSSOAuthentication(), 10000);
// If the promise is resolved because finishSSOAuthentication is called, stop the cancel promise. // If the promise is resolved because finishSSOAuthentication is called, stop the cancel promise.
// eslint-disable-next-line promise/catch-or-return // eslint-disable-next-line promise/catch-or-return
this.ssoAuthenticationDeferred.promise.then(() => clearTimeout(cancelTimeout)); this.ssoAuthenticationDeferred.then(() => clearTimeout(cancelTimeout));
} }
/** /**
@ -486,9 +487,7 @@ export class CoreAppProvider {
* @return Promise resolved once SSO authentication finishes. * @return Promise resolved once SSO authentication finishes.
*/ */
async waitForSSOAuthentication(): Promise<void> { async waitForSSOAuthentication(): Promise<void> {
const promise = this.ssoAuthenticationDeferred?.promise; await this.ssoAuthenticationDeferred;
await promise;
} }
/** /**
@ -497,7 +496,9 @@ export class CoreAppProvider {
* @param timeout Maximum time to wait, use null to wait forever. * @param timeout Maximum time to wait, use null to wait forever.
*/ */
async waitForResume(timeout: number | null = null): Promise<void> { async waitForResume(timeout: number | null = null): Promise<void> {
let deferred: PromiseDefer<void> | null = CoreUtils.promiseDefer<void>(); let deferred: CorePromisedValue<void> | null = new CorePromisedValue();
let resumeSubscription: Subscription | null = null;
let timeoutId: number | null = null;
const stopWaiting = () => { const stopWaiting = () => {
if (!deferred) { if (!deferred) {
@ -505,16 +506,16 @@ export class CoreAppProvider {
} }
deferred.resolve(); deferred.resolve();
resumeSubscription.unsubscribe(); resumeSubscription?.unsubscribe();
timeoutId && clearTimeout(timeoutId); timeoutId && clearTimeout(timeoutId);
deferred = null; deferred = null;
}; };
const resumeSubscription = Platform.resume.subscribe(stopWaiting); resumeSubscription = Platform.resume.subscribe(stopWaiting);
const timeoutId = timeout ? setTimeout(stopWaiting, timeout) : false; timeoutId = timeout ? window.setTimeout(stopWaiting, timeout) : null;
await deferred.promise; await deferred;
} }
/** /**

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { CorePromisedValue } from '@classes/promised-value';
import { CoreAppSchema } from '@services/app'; import { CoreAppSchema } from '@services/app';
import { PromiseDefer } from '@services/utils/utils';
/** /**
* Database variables for CoreLocalNotifications service. * Database variables for CoreLocalNotifications service.
@ -76,5 +76,5 @@ export const APP_SCHEMA: CoreAppSchema = {
export type CodeRequestsQueueItem = { export type CodeRequestsQueueItem = {
table: string; table: string;
id: string; id: string;
deferreds: PromiseDefer<number>[]; deferreds: CorePromisedValue<number>[];
}; };

View File

@ -26,7 +26,7 @@ import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUrlUtils } from '@services/utils/url'; import { CoreUrlUtils } from '@services/utils/url';
import { CoreUtils, CoreUtilsOpenFileOptions, PromiseDefer } from '@services/utils/utils'; import { CoreUtils, CoreUtilsOpenFileOptions } from '@services/utils/utils';
import { SQLiteDB } from '@classes/sqlitedb'; import { SQLiteDB } from '@classes/sqlitedb';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
@ -53,6 +53,7 @@ import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/da
import { lazyMap, LazyMap } from '../utils/lazy-map'; import { lazyMap, LazyMap } from '../utils/lazy-map';
import { asyncInstance, AsyncInstance } from '../utils/async-instance'; import { asyncInstance, AsyncInstance } from '../utils/async-instance';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CorePromisedValue } from '@classes/promised-value';
/* /*
* Factory for handling downloading files and retrieve downloaded files. * Factory for handling downloading files and retrieve downloaded files.
@ -94,7 +95,7 @@ export class CoreFilepoolProvider {
]; ];
// To handle file downloads using the queue. // To handle file downloads using the queue.
protected queueDeferreds: { [s: string]: { [s: string]: CoreFilepoolPromiseDefer } } = {}; protected queueDeferreds: { [s: string]: { [s: string]: CoreFilepoolPromisedValue } } = {};
protected sizeCache: {[fileUrl: string]: number} = {}; // A "cache" to store file sizes. protected sizeCache: {[fileUrl: string]: number} = {}; // A "cache" to store file sizes.
// Variables to prevent downloading packages/files twice at the same time. // Variables to prevent downloading packages/files twice at the same time.
protected packagesPromises: { [s: string]: { [s: string]: Promise<void> } } = {}; protected packagesPromises: { [s: string]: { [s: string]: Promise<void> } } = {};
@ -450,7 +451,7 @@ export class CoreFilepoolProvider {
this.logger.debug(`File ${fileId} already in queue and does not require update`); this.logger.debug(`File ${fileId} already in queue and does not require update`);
if (queueDeferred) { if (queueDeferred) {
// If we were able to retrieve the queue deferred before, we use that one. // If we were able to retrieve the queue deferred before, we use that one.
return queueDeferred.promise; return queueDeferred;
} else { } else {
// Create a new deferred and return its promise. // Create a new deferred and return its promise.
return this.getQueuePromise(siteId, fileId, true, onProgress); return this.getQueuePromise(siteId, fileId, true, onProgress);
@ -1889,7 +1890,7 @@ export class CoreFilepoolProvider {
fileId: string, fileId: string,
create: boolean = true, create: boolean = true,
onProgress?: CoreFilepoolOnProgressCallback, onProgress?: CoreFilepoolOnProgressCallback,
): CoreFilepoolPromiseDefer | undefined { ): CoreFilepoolPromisedValue | undefined {
if (!this.queueDeferreds[siteId]) { if (!this.queueDeferreds[siteId]) {
if (!create) { if (!create) {
return; return;
@ -1900,7 +1901,7 @@ export class CoreFilepoolProvider {
if (!create) { if (!create) {
return; return;
} }
this.queueDeferreds[siteId][fileId] = CoreUtils.promiseDefer(); this.queueDeferreds[siteId][fileId] = new CorePromisedValue();
} }
if (onProgress) { if (onProgress) {
@ -1938,9 +1939,7 @@ export class CoreFilepoolProvider {
create: boolean = true, create: boolean = true,
onProgress?: CoreFilepoolOnProgressCallback, onProgress?: CoreFilepoolOnProgressCallback,
): Promise<void> | undefined { ): Promise<void> | undefined {
const deferred = this.getQueueDeferred(siteId, fileId, create, onProgress); return this.getQueueDeferred(siteId, fileId, create, onProgress);
return deferred?.promise;
} }
/** /**
@ -3032,11 +3031,11 @@ export class CoreFilepoolProvider {
* @param error String identifier for error message, if rejected. * @param error String identifier for error message, if rejected.
*/ */
protected treatQueueDeferred(siteId: string, fileId: string, resolve: boolean, error?: string): void { protected treatQueueDeferred(siteId: string, fileId: string, resolve: boolean, error?: string): void {
if (this.queueDeferreds[siteId] && this.queueDeferreds[siteId][fileId]) { if (siteId in this.queueDeferreds && fileId in this.queueDeferreds[siteId]) {
if (resolve) { if (resolve) {
this.queueDeferreds[siteId][fileId].resolve(); this.queueDeferreds[siteId][fileId].resolve();
} else { } else {
this.queueDeferreds[siteId][fileId].reject(error); this.queueDeferreds[siteId][fileId].reject(new Error(error));
} }
delete this.queueDeferreds[siteId][fileId]; delete this.queueDeferreds[siteId][fileId];
} }
@ -3138,7 +3137,7 @@ export type CoreFilepoolOnProgressCallback<T = unknown> = (event: T) => void;
/** /**
* Deferred promise for file pool. It's similar to the result of $q.defer() in AngularJS. * Deferred promise for file pool. It's similar to the result of $q.defer() in AngularJS.
*/ */
type CoreFilepoolPromiseDefer = PromiseDefer<void> & { type CoreFilepoolPromisedValue = CorePromisedValue<void> & {
onProgress?: CoreFilepoolOnProgressCallback; // On Progress function. onProgress?: CoreFilepoolOnProgressCallback; // On Progress function.
}; };

View File

@ -20,7 +20,6 @@ import { CoreApp } from '@services/app';
import { CoreConfig } from '@services/config'; import { CoreConfig } from '@services/config';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreUtils } from '@services/utils/utils';
import { SQLiteDB } from '@classes/sqlitedb'; import { SQLiteDB } from '@classes/sqlitedb';
import { CoreQueueRunner } from '@classes/queue-runner'; import { CoreQueueRunner } from '@classes/queue-runner';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
@ -34,6 +33,7 @@ import {
SITES_TABLE_NAME, SITES_TABLE_NAME,
CodeRequestsQueueItem, CodeRequestsQueueItem,
} from '@services/database/local-notifications'; } from '@services/database/local-notifications';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Service to handle local notifications. * Service to handle local notifications.
@ -507,7 +507,7 @@ export class CoreLocalNotificationsProvider {
* @return Promise resolved when the code is retrieved. * @return Promise resolved when the code is retrieved.
*/ */
protected requestCode(table: string, id: string): Promise<number> { protected requestCode(table: string, id: string): Promise<number> {
const deferred = CoreUtils.promiseDefer<number>(); const deferred = new CorePromisedValue<number>();
const key = table + '#' + id; const key = table + '#' + id;
const isQueueEmpty = Object.keys(this.codeRequestsQueue).length == 0; const isQueueEmpty = Object.keys(this.codeRequestsQueue).length == 0;
@ -527,7 +527,7 @@ export class CoreLocalNotificationsProvider {
this.processNextRequest(); this.processNextRequest();
} }
return deferred.promise; return deferred;
} }
/** /**

View File

@ -21,9 +21,10 @@ import { makeSingleton } from '@singletons';
import { CoreH5P } from '@features/h5p/services/h5p'; import { CoreH5P } from '@features/h5p/services/h5p';
import { CoreLoginHelper } from '@features/login/services/login-helper'; import { CoreLoginHelper } from '@features/login/services/login-helper';
import { CoreSites } from './sites'; import { CoreSites } from './sites';
import { CoreUtils, PromiseDefer } from './utils/utils'; import { CoreUtils } from './utils/utils';
import { CoreApp } from './app'; import { CoreApp } from './app';
import { CoreZoomLevel } from '@features/settings/services/settings-helper'; import { CoreZoomLevel } from '@features/settings/services/settings-helper';
import { CorePromisedValue } from '@classes/promised-value';
const VERSION_APPLIED = 'version_applied'; const VERSION_APPLIED = 'version_applied';
@ -36,11 +37,11 @@ const VERSION_APPLIED = 'version_applied';
export class CoreUpdateManagerProvider { export class CoreUpdateManagerProvider {
protected logger: CoreLogger; protected logger: CoreLogger;
protected doneDeferred: PromiseDefer<void>; protected doneDeferred: CorePromisedValue<void>;
constructor() { constructor() {
this.logger = CoreLogger.getInstance('CoreUpdateManagerProvider'); this.logger = CoreLogger.getInstance('CoreUpdateManagerProvider');
this.doneDeferred = CoreUtils.promiseDefer(); this.doneDeferred = new CorePromisedValue();
} }
/** /**
@ -49,7 +50,7 @@ export class CoreUpdateManagerProvider {
* @return Promise resolved when the load function is done. * @return Promise resolved when the load function is done.
*/ */
get donePromise(): Promise<void> { get donePromise(): Promise<void> {
return this.doneDeferred.promise; return this.doneDeferred;
} }
/** /**

View File

@ -678,30 +678,29 @@ export class CoreDomUtilsProvider {
* Wait an element to exists using the findFunction. * Wait an element to exists using the findFunction.
* *
* @param findFunction The function used to find the element. * @param findFunction The function used to find the element.
* @param retries Number of retries before giving up.
* @param retryAfter Milliseconds to wait before retrying if the element wasn't found.
* @return Resolved if found, rejected if too many tries. * @return Resolved if found, rejected if too many tries.
* @deprecated since app 4.0 Use CoreDom.waitToBeInsideElement instead. * @deprecated since app 4.0 Use CoreDom.waitToBeInsideElement instead.
*/ */
waitElementToExist(findFunction: () => HTMLElement | null): Promise<HTMLElement> { async waitElementToExist(
const promiseInterval = CoreUtils.promiseDefer<HTMLElement>(); findFunction: () => HTMLElement | null,
let tries = 100; retries: number = 100,
retryAfter: number = 100,
): Promise<HTMLElement> {
const element = findFunction();
const clear = setInterval(() => { if (!element && retries === 0) {
const element: HTMLElement | null = findFunction(); throw Error('Element not found');
}
if (element) { if (!element) {
clearInterval(clear); await CoreUtils.wait(retryAfter);
promiseInterval.resolve(element);
} else {
tries--;
if (tries <= 0) { return this.waitElementToExist(findFunction, retries - 1);
clearInterval(clear); }
promiseInterval.reject();
}
}
}, 100);
return promiseInterval.promise; return element;
} }
/** /**

View File

@ -22,7 +22,7 @@ import { CoreFileHelper } from '@services/file-helper';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUrlUtils } from '@services/utils/url'; import { CoreUrlUtils } from '@services/utils/url';
import { CoreUtils, PromiseDefer } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { makeSingleton, Network, NgZone, Translate, Diagnostic } from '@singletons'; import { makeSingleton, Network, NgZone, Translate, Diagnostic } from '@singletons';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
@ -30,6 +30,7 @@ import { CoreUrl } from '@singletons/url';
import { CoreWindow } from '@singletons/window'; import { CoreWindow } from '@singletons/window';
import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper';
import { CoreText } from '@singletons/text'; import { CoreText } from '@singletons/text';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* Possible types of frame elements. * Possible types of frame elements.
@ -48,7 +49,7 @@ export class CoreIframeUtilsProvider {
static readonly FRAME_TAGS = ['iframe', 'frame', 'object', 'embed']; static readonly FRAME_TAGS = ['iframe', 'frame', 'object', 'embed'];
protected logger: CoreLogger; protected logger: CoreLogger;
protected waitAutoLoginDefer?: PromiseDefer<void>; protected waitAutoLoginDefer?: CorePromisedValue<void>;
constructor() { constructor() {
this.logger = CoreLogger.getInstance('CoreIframeUtilsProvider'); this.logger = CoreLogger.getInstance('CoreIframeUtilsProvider');
@ -193,14 +194,14 @@ export class CoreIframeUtilsProvider {
if (this.waitAutoLoginDefer) { if (this.waitAutoLoginDefer) {
// Another iframe is already using auto-login. Wait for it to finish. // Another iframe is already using auto-login. Wait for it to finish.
await this.waitAutoLoginDefer.promise; await this.waitAutoLoginDefer;
// Return the original URL, we can't request a new auto-login. // Return the original URL, we can't request a new auto-login.
return url; return url;
} }
// First iframe requesting auto-login. // First iframe requesting auto-login.
this.waitAutoLoginDefer = CoreUtils.promiseDefer(); this.waitAutoLoginDefer = new CorePromisedValue();
const finalUrl = await currentSite.getAutoLoginUrl(url, false); const finalUrl = await currentSite.getAutoLoginUrl(url, false);

View File

@ -34,6 +34,7 @@ import { CoreFileEntry } from '@services/file-helper';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreWindow } from '@singletons/window'; import { CoreWindow } from '@singletons/window';
import { CoreColors } from '@singletons/colors'; import { CoreColors } from '@singletons/colors';
import { CorePromisedValue } from '@classes/promised-value';
type TreeNode<T> = T & { children: TreeNode<T>[] }; type TreeNode<T> = T & { children: TreeNode<T>[] };
@ -48,7 +49,7 @@ export class CoreUtilsProvider {
protected logger: CoreLogger; protected logger: CoreLogger;
protected iabInstance?: InAppBrowserObject; protected iabInstance?: InAppBrowserObject;
protected uniqueIds: {[name: string]: number} = {}; protected uniqueIds: {[name: string]: number} = {};
protected qrScanData?: {deferred: PromiseDefer<string>; observable: Subscription}; protected qrScanData?: {deferred: CorePromisedValue<string>; observable: Subscription};
protected initialColorSchemeContent = 'light dark'; protected initialColorSchemeContent = 'light dark';
constructor() { constructor() {
@ -1325,18 +1326,13 @@ export class CoreUtilsProvider {
} }
/** /**
* Similar to AngularJS $q.defer(). * Create a deferred promise that can be resolved or rejected explicitly.
* *
* @return The deferred promise. * @return The deferred promise.
* @deprecated since app 4.1. Use CorePromisedValue instead.
*/ */
promiseDefer<T>(): PromiseDefer<T> { promiseDefer<T>(): CorePromisedValue<T> {
const deferred: Partial<PromiseDefer<T>> = {}; return new CorePromisedValue<T>();
deferred.promise = new Promise((resolve, reject): void => {
deferred.resolve = resolve as (value?: T | undefined) => void;
deferred.reject = reject;
});
return deferred as PromiseDefer<T>;
} }
/** /**
@ -1635,12 +1631,12 @@ export class CoreUtilsProvider {
if (this.qrScanData && this.qrScanData.deferred) { if (this.qrScanData && this.qrScanData.deferred) {
// Already scanning. // Already scanning.
return this.qrScanData.deferred.promise; return this.qrScanData.deferred;
} }
// Start scanning. // Start scanning.
this.qrScanData = { this.qrScanData = {
deferred: this.promiseDefer(), deferred: new CorePromisedValue(),
// When text is received, stop scanning and return the text. // When text is received, stop scanning and return the text.
observable: QRScanner.scan().subscribe(text => this.stopScanQR(text, false)), observable: QRScanner.scan().subscribe(text => this.stopScanQR(text, false)),
@ -1659,7 +1655,7 @@ export class CoreUtilsProvider {
colorSchemeMeta.setAttribute('content', 'normal'); colorSchemeMeta.setAttribute('content', 'normal');
} }
return this.qrScanData.deferred.promise; return this.qrScanData.deferred;
} catch (e) { } catch (e) {
this.stopScanQR(e, true); this.stopScanQR(e, true);
@ -1697,7 +1693,7 @@ export class CoreUtilsProvider {
this.qrScanData.observable.unsubscribe(); // Stop scanning. this.qrScanData.observable.unsubscribe(); // Stop scanning.
if (error) { if (error) {
this.qrScanData.deferred.reject(data); this.qrScanData.deferred.reject(typeof data === 'string' ? new Error(data) : data);
} else if (data !== undefined) { } else if (data !== undefined) {
this.qrScanData.deferred.resolve(data as string); this.qrScanData.deferred.resolve(data as string);
} else { } else {
@ -1769,30 +1765,6 @@ export class CoreUtilsProvider {
export const CoreUtils = makeSingleton(CoreUtilsProvider); export const CoreUtils = makeSingleton(CoreUtilsProvider);
/**
* Deferred promise. It's similar to the result of $q.defer() in AngularJS.
*/
export type PromiseDefer<T> = {
/**
* The promise.
*/
promise: Promise<T>;
/**
* Function to resolve the promise.
*
* @param value The resolve value.
*/
resolve: (value?: T) => void; // Function to resolve the promise.
/**
* Function to reject the promise.
*
* @param reason The reject param.
*/
reject: (reason?: unknown) => void;
};
/** /**
* Data for each entry of executeOrderedPromises. * Data for each entry of executeOrderedPromises.
*/ */

View File

@ -26,7 +26,6 @@ import { CoreApp } from '@services/app';
import { CoreFile, CoreFileFormat } from '@services/file'; import { CoreFile, CoreFileFormat } from '@services/file';
import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreTextErrorObject, CoreTextUtils } from '@services/utils/text'; import { CoreTextErrorObject, CoreTextUtils } from '@services/utils/text';
import { CoreUtils, PromiseDefer } from '@services/utils/utils';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { CoreInterceptor } from '@classes/interceptor'; import { CoreInterceptor } from '@classes/interceptor';
@ -38,6 +37,7 @@ import { CoreAjaxWSError } from '@classes/errors/ajaxwserror';
import { CoreNetworkError } from '@classes/errors/network-error'; import { CoreNetworkError } from '@classes/errors/network-error';
import { CoreSite } from '@classes/site'; import { CoreSite } from '@classes/site';
import { CoreHttpError } from '@classes/errors/httperror'; import { CoreHttpError } from '@classes/errors/httperror';
import { CorePromisedValue } from '@classes/promised-value';
/** /**
* This service allows performing WS calls and download/upload files. * This service allows performing WS calls and download/upload files.
@ -76,12 +76,12 @@ export class CoreWSProvider {
siteUrl, siteUrl,
data, data,
preSets, preSets,
deferred: CoreUtils.promiseDefer<T>(), deferred: new CorePromisedValue<T>(),
}; };
this.retryCalls.push(call); this.retryCalls.push(call);
return call.deferred.promise; return call.deferred;
} }
/** /**
@ -1363,7 +1363,7 @@ type RetryCall = {
siteUrl: string; siteUrl: string;
data: Record<string, unknown>; data: Record<string, unknown>;
preSets: CoreWSPreSets; preSets: CoreWSPreSets;
deferred: PromiseDefer<unknown>; deferred: CorePromisedValue;
}; };
/** /**