@theia/core
Version:
Theia is a cloud & desktop IDE framework implemented in TypeScript.
133 lines • 5.08 kB
JavaScript
// *****************************************************************************
// Copyright (C) 2017 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
Object.defineProperty(exports, "__esModule", { value: true });
exports.firstTrue = exports.isThenable = exports.waitForEvent = exports.wait = exports.delay = exports.retry = exports.timeoutReject = exports.timeout = exports.Deferred = void 0;
const cancellation_1 = require("./cancellation");
const types_1 = require("./types");
/**
* Simple implementation of the deferred pattern.
* An object that exposes a promise and functions to resolve and reject it.
*/
class Deferred {
constructor() {
this.state = 'unresolved';
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
}).then(res => (this.setState('resolved'), res), err => (this.setState('rejected'), Promise.reject(err)));
}
setState(state) {
if (this.state === 'unresolved') {
this.state = state;
}
}
}
exports.Deferred = Deferred;
/**
* @returns resolves after a specified number of milliseconds
* @throws cancelled if a given token is cancelled before a specified number of milliseconds
*/
function timeout(ms, token = cancellation_1.CancellationToken.None) {
const deferred = new Deferred();
const handle = setTimeout(() => deferred.resolve(), ms);
token.onCancellationRequested(() => {
clearTimeout(handle);
deferred.reject((0, cancellation_1.cancelled)());
});
return deferred.promise;
}
exports.timeout = timeout;
/**
* Creates a promise that is rejected after the given amount of time. A typical use case is to wait for another promise until a specified timeout using:
* ```
* Promise.race([ promiseToPerform, timeoutReject(timeout, 'Timeout error message') ]);
* ```
*
* @param ms timeout in milliseconds
* @param message error message on promise rejection
* @returns rejection promise
*/
function timeoutReject(ms, message) {
const deferred = new Deferred();
setTimeout(() => deferred.reject(new Error(message)), ms);
return deferred.promise;
}
exports.timeoutReject = timeoutReject;
async function retry(task, retryDelay, retries) {
let lastError;
for (let i = 0; i < retries; i++) {
try {
return await task();
}
catch (error) {
lastError = error;
await timeout(retryDelay);
}
}
throw lastError;
}
exports.retry = retry;
/**
* A function to allow a promise resolution to be delayed by a number of milliseconds. Usage is as follows:
*
* `const stringValue = await myPromise.then(delay(600)).then(value => value.toString());`
*
* @param ms the number of millisecond to delay
* @returns a function that returns a promise that returns the given value, but delayed
*/
function delay(ms) {
return value => new Promise((resolve, reject) => { setTimeout(() => resolve(value), ms); });
}
exports.delay = delay;
/**
* Constructs a promise that will resolve after a given delay.
* @param ms the number of milliseconds to wait
*/
async function wait(ms) {
await delay(ms)(undefined);
}
exports.wait = wait;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function waitForEvent(event, ms, thisArg, disposables) {
return new Promise((resolve, reject) => {
const registration = setTimeout(() => {
listener.dispose();
reject(new cancellation_1.CancellationError());
}, ms);
const listener = event((evt) => {
clearTimeout(registration);
listener.dispose();
resolve(evt);
}, thisArg, disposables);
});
}
exports.waitForEvent = waitForEvent;
function isThenable(obj) {
return (0, types_1.isObject)(obj) && (0, types_1.isFunction)(obj.then);
}
exports.isThenable = isThenable;
/**
* Returns with a promise that waits until the first promise resolves to `true`.
*/
// Based on https://stackoverflow.com/a/51160727/5529090
function firstTrue(...promises) {
const newPromises = promises.map(promise => new Promise((resolve, reject) => promise.then(result => result && resolve(true), reject)));
newPromises.push(Promise.all(promises).then(() => false));
return Promise.race(newPromises);
}
exports.firstTrue = firstTrue;
//# sourceMappingURL=promise-util.js.map
;