/
githubmirror
/
amphtml
Обзор
Документация
Войти
/
githubmirror
/
amphtml
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/core/data-structures/promise.js
127 строк
3 KB
Jake Fried
Core Typechecking: enable noImplicitAny (#37201)
14 дек 2021, 02:31
Не верифицирован
14 дек 2021, 02:31
1f332cf
Код
Авторство
О чём код?
/** @type {undefined|Promise<void>}| */ let resolved; /** * Returns a cached resolved promise. * Babel converts direct calls to Promise.resolve() (with no arguments) into * calls to this. * * @return {Promise<void>} */ export function resolvedPromise() { if (resolved) { return resolved; } // It's important that we call with `undefined` here, to prevent a transform // recursion. If we didn't pass an arg, then the transformer would replace // this callsite with a call to `resolvedPromise()`. resolved = Promise.resolve(undefined); return resolved; } /** * Returns a Deferred struct, which holds a pending promise and its associated * resolve and reject functions. * * This is preferred instead of creating a Promise instance to extract the * resolve/reject functions yourself: * * ``` * // Avoid doing * let resolve; * const promise = new Promise(res => { * resolve = res; * }); * * // Good * const deferred = new Deferred(); * const { promise, resolve } = deferred; * ``` * * @template T */ export class Deferred { /** Constructor. */ constructor() { /** @const {Promise<T>} */ this.promise = new /*OK*/ Promise((res, rej) => { /** @const {function(T=)} */ this.resolve = res; /** @const {function(*=)} */ this.reject = rej; }); } } /** * Creates a promise resolved to the return value of fn. * If fn sync throws, it will cause the promise to reject. * * @param {function():(T|Promise<T>)} fn * @return {Promise<T>} * @template T */ export function tryResolve(fn) { return new Promise((resolve) => { resolve(fn()); }); } /** * Resolves with the result of the last promise added. * @implements {PromiseLike<T>} * @template T */ export class LastAddedResolver { /** * @param {Array<PromiseLike<T>>=} opt_promises */ constructor(opt_promises) { /** @private @const {Deferred<T>} */ this.deferred_ = new Deferred(); /** @private */ this.count_ = 0; if (opt_promises) { for (const promise of opt_promises) { this.add(promise); } } } /** * Add a promise to possibly be resolved. * @param {PromiseLike<T>} promise * @return {Promise<T>} */ add(promise) { const countAtAdd = ++this.count_; promise.then( (result) => { if (this.count_ === countAtAdd) { this.deferred_.resolve(result); } }, (error) => { // Don't follow behavior of Promise.all and Promise.race error so that // this will only reject when most recently added promise fails. if (this.count_ === countAtAdd) { this.deferred_.reject(error); } } ); return this.deferred_.promise; } /** * Bind handlers for when the last added promise resolves/rejects. * @param {function(T):?} [opt_resolve] * @param {function(?):?} [opt_reject] * @return {Promise<?>} */ then(opt_resolve, opt_reject) { return this.deferred_.promise.then(opt_resolve, opt_reject); } }