UNPKG

monaco-editor-core

Version:

A browser based code editor

106 lines (105 loc) 3.5 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { autorun } from './autorun.js'; import { observableValue, transaction } from './base.js'; import { CancellationError } from '../errors.js'; /** * A promise whose state is observable. */ export class ObservablePromise { static fromFn(fn) { return new ObservablePromise(fn()); } constructor(promise) { this._value = observableValue(this, undefined); /** * The current state of the promise. * Is `undefined` if the promise didn't resolve yet. */ this.promiseResult = this._value; this.promise = promise.then(value => { transaction(tx => { /** @description onPromiseResolved */ this._value.set(new PromiseResult(value, undefined), tx); }); return value; }, error => { transaction(tx => { /** @description onPromiseRejected */ this._value.set(new PromiseResult(undefined, error), tx); }); throw error; }); } } export class PromiseResult { constructor( /** * The value of the resolved promise. * Undefined if the promise rejected. */ data, /** * The error in case of a rejected promise. * Undefined if the promise resolved. */ error) { this.data = data; this.error = error; } } export function waitForState(observable, predicate, isError, cancellationToken) { if (!predicate) { predicate = state => state !== null && state !== undefined; } return new Promise((resolve, reject) => { let isImmediateRun = true; let shouldDispose = false; const stateObs = observable.map(state => { /** @description waitForState.state */ return { isFinished: predicate(state), error: isError ? isError(state) : false, state }; }); const d = autorun(reader => { /** @description waitForState */ const { isFinished, error, state } = stateObs.read(reader); if (isFinished || error) { if (isImmediateRun) { // The variable `d` is not initialized yet shouldDispose = true; } else { d.dispose(); } if (error) { reject(error === true ? state : error); } else { resolve(state); } } }); if (cancellationToken) { const dc = cancellationToken.onCancellationRequested(() => { d.dispose(); dc.dispose(); reject(new CancellationError()); }); if (cancellationToken.isCancellationRequested) { d.dispose(); dc.dispose(); reject(new CancellationError()); return; } } isImmediateRun = false; if (shouldDispose) { d.dispose(); } }); }