Monorepo for Aesthetic.Computer aesthetic.computer
at main 56 lines 1.6 kB view raw
1import { Disposable, Event, EventEmitter } from "vscode"; 2 3export interface PromiseAdapter<T, U> { 4 ( 5 value: T, 6 resolve: 7 (value: U | PromiseLike<U>) => void, 8 reject: 9 (reason: any) => void 10 ): any; 11} 12 13const passthrough = (value: any, resolve: (value?: any) => void) => resolve(value); 14 15/** 16 * Return a promise that resolves with the next emitted event, or with some future 17 * event as decided by an adapter. 18 * 19 * If specified, the adapter is a function that will be called with 20 * `(event, resolve, reject)`. It will be called once per event until it resolves or 21 * rejects. 22 * 23 * The default adapter is the passthrough function `(value, resolve) => resolve(value)`. 24 * 25 * @param event the event 26 * @param adapter controls resolution of the returned promise 27 * @returns a promise that resolves or rejects as specified by the adapter 28 */ 29 export function promiseFromEvent<T, U>(event: Event<T>, adapter: PromiseAdapter<T, U> = passthrough): { promise: Promise<U>; cancel: EventEmitter<void> } { 30 let subscription: Disposable; 31 let cancel = new EventEmitter<void>(); 32 33 return { 34 promise: new Promise<U>((resolve, reject) => { 35 cancel.event(_ => reject('Cancelled')); 36 subscription = event((value: T) => { 37 try { 38 Promise.resolve(adapter(value, resolve, reject)) 39 .catch(reject); 40 } catch (error) { 41 reject(error); 42 } 43 }); 44 }).then( 45 (result: U) => { 46 subscription.dispose(); 47 return result; 48 }, 49 error => { 50 subscription.dispose(); 51 throw error; 52 } 53 ), 54 cancel 55 }; 56}