Created
January 12, 2022 07:53
-
-
Save fronterior/9e9a28a840334c374c46df74d958add6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TPromise<T> extends Promise<T> { | |
static TimeoutError = class extends Error {}; | |
constructor( | |
f: ( | |
resolve: (value: T | PromiseLike<T>) => void, | |
reject: (reason?: any) => void | |
) => void, | |
timeout: number = Infinity | |
) { | |
let resolve, reject; | |
super((res, rej) => { | |
resolve = res; | |
reject = rej; | |
}); | |
const timer = | |
timeout === Infinity | |
? null | |
: setTimeout(() => { | |
reject( | |
new TPromise.TimeoutError(`Load timeout for promise: ${timeout}`) | |
); | |
}, timeout); | |
f( | |
(val: T | PromiseLike<T>) => { | |
resolve(val); | |
clearTimeout(timer); | |
}, | |
(err) => { | |
reject(err); | |
clearTimeout(timer); | |
} | |
); | |
} | |
} | |
class ImageLoader extends TPromise<HTMLImageElement> { | |
static CancelError = class extends Error {}; | |
public img: HTMLImageElement; | |
constructor( | |
src: string, | |
{ | |
timeout = Infinity, | |
crossOrigin, | |
}: Partial<{ | |
timeout: number; | |
crossOrigin: string; | |
}> = {} | |
) { | |
const img = new Image(); | |
const p = new TPromise<HTMLImageElement>((resolve, reject) => { | |
if (timeout !== Infinity) | |
setTimeout(() => { | |
reject(new Error(`Load timeout for [${src}]:${timeout}ms`)); | |
}, timeout); | |
img.crossOrigin = crossOrigin; | |
img.onload = () => { | |
resolve(img); | |
}; | |
img.onerror = (err) => { | |
if (img.getAttribute("src") === "") | |
reject(new ImageLoader.CancelError(`Cancel image loading.`)); | |
else reject(err); | |
}; | |
img.src = src; | |
}, timeout).catch((err) => { | |
if (err instanceof TPromise.TimeoutError) img.removeAttribute("src"); | |
throw err; | |
}); | |
super((res, rej) => p.then(res, rej)); | |
this.img = img; | |
} | |
cancel() { | |
this.img.src = ""; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment