UNPKG

@euirim/microsoft-cognitiveservices-speech-sdk

Version:
340 lines (338 loc) 12.3 kB
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. import { ArgumentNullError } from "./Error"; export var PromiseState; (function (PromiseState) { PromiseState[PromiseState["None"] = 0] = "None"; PromiseState[PromiseState["Resolved"] = 1] = "Resolved"; PromiseState[PromiseState["Rejected"] = 2] = "Rejected"; })(PromiseState || (PromiseState = {})); export class PromiseResult { constructor(promiseResultEventSource) { this.throwIfError = () => { if (this.isError) { throw this.error; } }; promiseResultEventSource.on((result) => { if (!this.privIsCompleted) { this.privIsCompleted = true; this.privIsError = false; this.privResult = result; } }, (error) => { if (!this.privIsCompleted) { this.privIsCompleted = true; this.privIsError = true; this.privError = error; } }); } get isCompleted() { return this.privIsCompleted; } get isError() { return this.privIsError; } get error() { return this.privError; } get result() { return this.privResult; } } // tslint:disable-next-line:max-classes-per-file export class PromiseResultEventSource { constructor() { this.setResult = (result) => { this.privOnSetResult(result); }; this.setError = (error) => { this.privOnSetError(error); }; this.on = (onSetResult, onSetError) => { this.privOnSetResult = onSetResult; this.privOnSetError = onSetError; }; } } // tslint:disable-next-line:max-classes-per-file export class PromiseHelper { } PromiseHelper.whenAll = (promises) => { if (!promises || promises.length === 0) { throw new ArgumentNullError("promises"); } const deferred = new Deferred(); const errors = []; let completedPromises = 0; const checkForCompletion = () => { completedPromises++; if (completedPromises === promises.length) { if (errors.length === 0) { deferred.resolve(true); } else { deferred.reject(errors.join(", ")); } } }; for (const promise of promises) { promise.on((r) => { checkForCompletion(); }, (e) => { errors.push(e); checkForCompletion(); }); } return deferred.promise(); }; PromiseHelper.fromResult = (result) => { const deferred = new Deferred(); deferred.resolve(result); return deferred.promise(); }; PromiseHelper.fromError = (error) => { const deferred = new Deferred(); deferred.reject(error); return deferred.promise(); }; // TODO: replace with ES6 promises // tslint:disable-next-line:max-classes-per-file export class Promise { constructor(sink) { this.result = () => { return this.privSink.result; }; this.continueWith = (continuationCallback) => { if (!continuationCallback) { throw new ArgumentNullError("continuationCallback"); } const continuationDeferral = new Deferred(); this.privSink.on((r) => { try { const continuationResult = continuationCallback(this.privSink.result); continuationDeferral.resolve(continuationResult); } catch (e) { continuationDeferral.reject(e); } }, (error) => { try { const continuationResult = continuationCallback(this.privSink.result); continuationDeferral.resolve(continuationResult); } catch (e) { continuationDeferral.reject(`'Error handler for error ${error} threw error ${e}'`); } }); return continuationDeferral.promise(); }; this.onSuccessContinueWith = (continuationCallback) => { if (!continuationCallback) { throw new ArgumentNullError("continuationCallback"); } const continuationDeferral = new Deferred(); this.privSink.on((r) => { try { const continuationResult = continuationCallback(r); continuationDeferral.resolve(continuationResult); } catch (e) { continuationDeferral.reject(e); } }, (error) => { continuationDeferral.reject(error); }); return continuationDeferral.promise(); }; this.continueWithPromise = (continuationCallback) => { if (!continuationCallback) { throw new ArgumentNullError("continuationCallback"); } const continuationDeferral = new Deferred(); this.privSink.on((r) => { try { const continuationPromise = continuationCallback(this.privSink.result); if (!continuationPromise) { throw new Error("'Continuation callback did not return promise'"); } continuationPromise.on((continuationResult) => { continuationDeferral.resolve(continuationResult); }, (e) => { continuationDeferral.reject(e); }); } catch (e) { continuationDeferral.reject(e); } }, (error) => { try { const continuationPromise = continuationCallback(this.privSink.result); if (!continuationPromise) { throw new Error("Continuation callback did not return promise"); } continuationPromise.on((continuationResult) => { continuationDeferral.resolve(continuationResult); }, (e) => { continuationDeferral.reject(e); }); } catch (e) { continuationDeferral.reject(`'Error handler for error ${error} threw error ${e}'`); } }); return continuationDeferral.promise(); }; this.onSuccessContinueWithPromise = (continuationCallback) => { if (!continuationCallback) { throw new ArgumentNullError("continuationCallback"); } const continuationDeferral = new Deferred(); this.privSink.on((r) => { try { const continuationPromise = continuationCallback(r); if (!continuationPromise) { throw new Error("Continuation callback did not return promise"); } continuationPromise.on((continuationResult) => { continuationDeferral.resolve(continuationResult); }, (e) => { continuationDeferral.reject(e); }); } catch (e) { continuationDeferral.reject(e); } }, (error) => { continuationDeferral.reject(error); }); return continuationDeferral.promise(); }; this.on = (successCallback, errorCallback) => { if (!successCallback) { throw new ArgumentNullError("successCallback"); } if (!errorCallback) { throw new ArgumentNullError("errorCallback"); } this.privSink.on(successCallback, errorCallback); return this; }; this.finally = (callback) => { if (!callback) { throw new ArgumentNullError("callback"); } const callbackWrapper = (_) => { callback(); }; return this.on(callbackWrapper, callbackWrapper); }; this.privSink = sink; } } // tslint:disable-next-line:max-classes-per-file export class Deferred { constructor() { this.state = () => { return this.privSink.state; }; this.promise = () => { return this.privPromise; }; this.resolve = (result) => { this.privSink.resolve(result); return this; }; this.reject = (error) => { this.privSink.reject(error); return this; }; this.privSink = new Sink(); this.privPromise = new Promise(this.privSink); } } // tslint:disable-next-line:max-classes-per-file export class Sink { constructor() { this.privState = PromiseState.None; this.privPromiseResult = null; this.privPromiseResultEvents = null; this.privSuccessHandlers = []; this.privErrorHandlers = []; this.resolve = (result) => { if (this.privState !== PromiseState.None) { throw new Error("'Cannot resolve a completed promise'"); } this.privState = PromiseState.Resolved; this.privPromiseResultEvents.setResult(result); for (let i = 0; i < this.privSuccessHandlers.length; i++) { this.executeSuccessCallback(result, this.privSuccessHandlers[i], this.privErrorHandlers[i]); } this.detachHandlers(); }; this.reject = (error) => { if (this.privState !== PromiseState.None) { throw new Error("'Cannot reject a completed promise'"); } this.privState = PromiseState.Rejected; this.privPromiseResultEvents.setError(error); for (const errorHandler of this.privErrorHandlers) { this.executeErrorCallback(error, errorHandler); } this.detachHandlers(); }; this.on = (successCallback, errorCallback) => { if (successCallback == null) { successCallback = (r) => { return; }; } if (this.privState === PromiseState.None) { this.privSuccessHandlers.push(successCallback); this.privErrorHandlers.push(errorCallback); } else { if (this.privState === PromiseState.Resolved) { this.executeSuccessCallback(this.privPromiseResult.result, successCallback, errorCallback); } else if (this.privState === PromiseState.Rejected) { this.executeErrorCallback(this.privPromiseResult.error, errorCallback); } this.detachHandlers(); } }; this.executeSuccessCallback = (result, successCallback, errorCallback) => { try { successCallback(result); } catch (e) { this.executeErrorCallback(`'Unhandled callback error: ${e}'`, errorCallback); } }; this.executeErrorCallback = (error, errorCallback) => { if (errorCallback) { try { errorCallback(error); } catch (e) { throw new Error(`'Unhandled callback error: ${e}. InnerError: ${error}'`); } } else { throw new Error(`'Unhandled error: ${error}'`); } }; this.detachHandlers = () => { this.privErrorHandlers = []; this.privSuccessHandlers = []; }; this.privPromiseResultEvents = new PromiseResultEventSource(); this.privPromiseResult = new PromiseResult(this.privPromiseResultEvents); } get state() { return this.privState; } get result() { return this.privPromiseResult; } } //# sourceMappingURL=Promise.js.map