@livelybone/promise-wait
Version:
A lib with some method about wait apis, including wait, waitUntil
114 lines (108 loc) • 4.25 kB
JavaScript
/**
* Bundle of @livelybone/promise-wait
* Generated: 2025-11-26
* Version: 1.3.1
* License: MIT
* Author: 2631541504@qq.com
*/
function ejectPromise() {
// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
var callbacks = {
resolve: function resolve(_) {},
reject: function reject(_) {}
};
var pro = new Promise(function (res, rej) {
callbacks.resolve = res;
callbacks.reject = rej;
});
return Object.assign(pro, callbacks);
}
function wait(timeout) {
var promise = ejectPromise();
var timer = setTimeout(promise.resolve, timeout);
return Object.assign(promise, {
stop: function stop() {
return clearTimeout(timer);
}
});
}
/**
* Options for `waitUntil` polling behavior.
*
* - `timeout` controls the overall maximum wait time.
* - `resolveTimeout` changes timeout behavior from reject to a resolved marker.
* - `interval` controls how frequently the `until` callback is evaluated.
*/
/**
* Parameters passed to the `until` callback in `waitUntil`.
*/
/**
* @param until
* @param options
* @returns
*/
/**
* Repeatedly evaluates the `until` callback until it returns a truthy value, then resolves with that value.
*
* Field logic and behavior:
* - The `until` callback may be synchronous or return a Promise. Its return is evaluated by JS truthiness:
* - If the resolved/returned value is truthy, the promise resolves immediately with that value.
* - If falsy (`false`, `0`, `''`, `null`, `undefined`, `NaN`), polling continues until the condition is met or timed out.
* - `options.timeout` (ms, default 10000): the maximum total wait time.
* - `options.interval` (ms, default 50): delay between `until` evaluations.
* - `options.resolveTimeout` (default false):
* - `true` → resolve with `{ timeout: true }` when hitting timeout.
* - `false` → reject with `Error('waitUntil: timeout')` when hitting timeout.
* - Cancellation: the returned promise has `cancel()` to stop further interval polling; the overall timeout timer is not
* cleared by `cancel()`, so final resolution/rejection still follows the timeout behavior above.
* - Errors: if `until` throws synchronously or returns a rejected Promise, the error is logged and the returned promise
* rejects immediately; no further polling occurs. This rejection is independent of `timeout`/`resolveTimeout`.
*
* @param until Function invoked every interval with `{ count, passedTime }`.
* @param options Polling configuration; see details above.
* @returns A promise resolving to `T` (truthy value from `until`) or `{ timeout: true }` (when `resolveTimeout` is true),
* plus a `cancel()` method to stop interval polling.
*/
function waitUntil(until, options) {
var _options$timeout, _options$interval;
var pro = ejectPromise();
var timeout = (_options$timeout = options === null || options === void 0 ? void 0 : options.timeout) !== null && _options$timeout !== void 0 ? _options$timeout : 10000;
var timeoutErr = new Error('waitUntil: timeout');
var intervalTimer;
var timer = setTimeout(function () {
clearTimeout(intervalTimer);
return options !== null && options !== void 0 && options.resolveTimeout ? pro.resolve({
timeout: true
}) : pro.reject(timeoutErr);
}, timeout);
var interval = (_options$interval = options === null || options === void 0 ? void 0 : options.interval) !== null && _options$interval !== void 0 ? _options$interval : 50;
var startTime = Date.now();
var count = 0;
var _runInterval = function runInterval() {
var passedTime = Date.now() - startTime;
count += 1;
Promise.resolve().then(function () {
return until({
count: count,
passedTime: passedTime
});
}).then(function ($val) {
if ($val) {
pro.resolve($val);
clearTimeout(timer);
} else if (passedTime < timeout) {
intervalTimer = setTimeout(_runInterval, interval);
}
}).catch(function (err) {
clearTimeout(intervalTimer);
pro.reject(err);
});
};
_runInterval();
return Object.assign(pro, {
cancel: function cancel() {
return clearTimeout(intervalTimer);
}
});
}
export { ejectPromise, wait, waitUntil };