@whatwg-node/promise-helpers
Version:
Promise helpers
124 lines (123 loc) • 3.37 kB
JavaScript
export function isPromise(value) {
return isPromiseLike(value);
}
export function isPromiseLike(value) {
return value?.then != null;
}
export function handleMaybePromiseLike(inputFactory, outputSuccessFactory, outputErrorFactory) {
function _handleMaybePromiseLike() {
const input$ = inputFactory();
if (isPromiseLike(input$)) {
return input$.then(outputSuccessFactory, outputErrorFactory);
}
return outputSuccessFactory(input$);
}
if (!outputErrorFactory) {
return _handleMaybePromiseLike();
}
try {
return _handleMaybePromiseLike();
}
catch (err) {
return outputErrorFactory(err);
}
}
export function handleMaybePromise(inputFactory, outputSuccessFactory, outputErrorFactory) {
return handleMaybePromiseLike(inputFactory, outputSuccessFactory, outputErrorFactory);
}
export function fakePromise(value) {
if (isPromise(value)) {
return value;
}
// Write a fake promise to avoid the promise constructor
// being called with `new Promise` in the browser.
return {
then(resolve) {
if (resolve) {
const callbackResult = resolve(value);
if (isPromise(callbackResult)) {
return callbackResult;
}
return fakePromise(callbackResult);
}
return this;
},
catch() {
return this;
},
finally(cb) {
if (cb) {
const callbackResult = cb();
if (isPromise(callbackResult)) {
return callbackResult.then(() => value, () => value);
}
return fakePromise(value);
}
return this;
},
[Symbol.toStringTag]: 'Promise',
};
}
export function createDeferredPromise() {
if (Promise.withResolvers) {
return Promise.withResolvers();
}
let resolveFn;
let rejectFn;
const promise = new Promise(function deferredPromiseExecutor(resolve, reject) {
resolveFn = resolve;
rejectFn = reject;
});
return {
promise,
get resolve() {
return resolveFn;
},
get reject() {
return rejectFn;
},
};
}
export function iterateAsyncVoid(iterable, callback) {
const iterator = iterable[Symbol.iterator]();
let stopEarlyFlag = false;
function stopEarlyFn() {
stopEarlyFlag = true;
}
function iterate() {
const { done: endOfIterator, value } = iterator.next();
if (endOfIterator) {
return;
}
return handleMaybePromise(() => callback(value, stopEarlyFn), () => {
if (stopEarlyFlag) {
return;
}
return iterate();
});
}
return iterate();
}
export function fakeRejectPromise(error) {
if (isPromise(error)) {
return error;
}
return {
then() {
return this;
},
catch(reject) {
if (reject) {
return fakePromise(reject(error));
}
return this;
},
finally(cb) {
if (cb) {
cb();
}
return this;
},
[Symbol.toStringTag]: 'Promise',
};
}