diff options
Diffstat (limited to 'app/assets/javascripts/lib/utils/tappable_promise.js')
-rw-r--r-- | app/assets/javascripts/lib/utils/tappable_promise.js | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/app/assets/javascripts/lib/utils/tappable_promise.js b/app/assets/javascripts/lib/utils/tappable_promise.js new file mode 100644 index 00000000000..8d327dabe1b --- /dev/null +++ b/app/assets/javascripts/lib/utils/tappable_promise.js @@ -0,0 +1,49 @@ +/** + * A promise that is also tappable, i.e. something you can subscribe + * to to get progress of a promise until it resolves. + * + * @example Usage + * const tp = new TappablePromise((resolve, reject, tap) => { + * for (let i = 0; i < 10; i++) { + * tap(i/10); + * } + * resolve(); + * }); + * + * tp.tap((progress) => { + * console.log(progress); + * }).then(() => { + * console.log('done'); + * }); + * + * // Output: + * // 0 + * // 0.1 + * // 0.2 + * // ... + * // 0.9 + * // done + * + * + * @param {(resolve: Function, reject: Function, tap: Function) => void} callback + * @returns {Promise & { tap: Function }}} + */ +export default function TappablePromise(callback) { + let progressCallback; + + const promise = new Promise((resolve, reject) => { + try { + const tap = (progress) => progressCallback?.(progress); + resolve(callback(tap, resolve, reject)); + } catch (e) { + reject(e); + } + }); + + promise.tap = function tap(_progressCallback) { + progressCallback = _progressCallback; + return this; + }; + + return promise; +} |