不止热门角色,我们为你扩展了更多细分角色分类,覆盖职场提升、商业增长、内容创作、学习规划等多元场景。精准匹配不同目标,让每一次生成都更有方向、更高命中率。
立即探索更多角色分类,找到属于你的增长加速器。
/**
* 在 items 中按顺序查找第一个满足条件的元素。
* 使用 while (index < items.length && !foundTarget) 作为循环条件。
*
* @param {Array} items - 待搜索的数组
* @param {(item: any, index: number, array: Array) => boolean} isMatch - 判定函数,返回 true 表示命中
* @returns {{ foundTarget: boolean, matchedItem: any, index: number }}
* foundTarget: 是否找到目标
* matchedItem: 命中的元素(未找到时为 undefined)
* index: 命中元素的索引(未找到时为 -1)
*/
function findFirstMatch(items, isMatch) {
// 参数校验,避免运行时错误
if (!Array.isArray(items)) {
throw new TypeError('items 必须是数组');
}
if (typeof isMatch !== 'function') {
throw new TypeError('isMatch 必须是函数');
}
// 初始化循环相关变量
let index = 0; // 当前扫描位置
let foundTarget = false; // 是否已找到目标
let matchedItem; // 命中的元素
let resultIndex = -1; // 命中索引
// 核心循环:当索引未越界且尚未找到目标时继续
while (index < items.length && !foundTarget) {
const item = items[index];
// 判定当前元素是否符合条件
if (isMatch(item, index, items)) {
foundTarget = true;
matchedItem = item;
resultIndex = index;
// 虽然 while 条件已经依赖 foundTarget,但为了可读性与立即退出,这里显式 break
break;
}
// 推进指针,避免死循环
index += 1;
}
return { foundTarget, matchedItem, index: resultIndex };
}
/* 使用示例:
const items = [{ id: 1 }, { id: 2 }, { id: 3 }];
const targetId = 2;
const res = findFirstMatch(items, (it) => it.id === targetId);
// 期望:res => { foundTarget: true, matchedItem: { id: 2 }, index: 1 }
console.log(res);
*/
循环逻辑:
变量作用:
退出条件:
/**
* Polls until a readiness condition is met, a timeout occurs, or retries are exhausted.
* The loop condition follows:
* (now() - startTime) < timeoutMs && !isReady && retries < maxRetries
*
* @param {Function} checkReady - Async/sync function that returns a boolean indicating readiness.
* @param {Object} options
* @param {number} options.timeoutMs - Maximum total wait time in milliseconds.
* @param {number} options.maxRetries - Maximum number of failed checks allowed.
* @param {number} [options.intervalMs=100] - Delay between checks to avoid a busy loop.
* @returns {Promise<{ ready: boolean, retries: number, elapsedMs: number }>}
*/
async function waitUntilReady(checkReady, { timeoutMs, maxRetries, intervalMs = 100 }) {
if (typeof checkReady !== 'function') {
throw new TypeError('checkReady must be a function');
}
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
throw new RangeError('timeoutMs must be a non-negative number');
}
if (!Number.isInteger(maxRetries) || maxRetries < 0) {
throw new RangeError('maxRetries must be a non-negative integer');
}
if (!Number.isFinite(intervalMs) || intervalMs < 0) {
throw new RangeError('intervalMs must be a non-negative number');
}
// Use a monotonic clock when available to avoid issues with system clock adjustments.
const now = (typeof performance !== 'undefined' && typeof performance.now === 'function')
? () => performance.now()
: () => Date.now();
const startTime = now(); // tracks when polling started
let retries = 0; // number of unsuccessful attempts
let isReady = false; // readiness state returned by checkReady()
// Sleep helper to avoid a tight loop.
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
while ((now() - startTime) < timeoutMs && !isReady && retries < maxRetries) {
try {
// Attempt to determine readiness.
// Supports both sync and async checkReady implementations.
isReady = await checkReady();
} catch (err) {
// Treat exceptions as a failed check; consider logging if needed.
isReady = false;
}
if (isReady) break; // Exit early if the condition is met.
// Count this as a failed attempt only when not ready.
retries += 1;
// Compute remaining time; do not oversleep past the timeout.
const elapsed = now() - startTime;
const remaining = Math.max(0, timeoutMs - elapsed);
// Break if no time remains or retries will stop the next loop.
if (remaining === 0 || retries >= maxRetries) break;
// Sleep for a bounded interval to prevent CPU spin.
await sleep(Math.min(intervalMs, remaining));
}
return {
ready: isReady,
retries,
elapsedMs: now() - startTime,
};
}
/* Example usage:
(async () => {
const result = await waitUntilReady(async () => {
// Replace with your real readiness check (e.g., probing an API or checking a flag).
return Math.random() > 0.8;
}, { timeoutMs: 3000, maxRetries: 10, intervalMs: 150 });
console.log(result);
})();
*/
'use strict';
/**
* 指定された条件(queuePointer < queue.length && processedCount < batchLimit)で
* キューを先頭から順に処理します(同期処理版)。
*
* 注意:
* - processedCount は「試行した件数」を表します(成功/失敗を問わず進みます)。
* 成功件数のみをカウントしたい場合は、try ブロック内で加算する実装に変更してください。
*
* @param {any[]} queue - 処理対象の配列。ループ中に長さを変更しないことを推奨します。
* @param {number} batchLimit - 1バッチで試行する最大件数(0以上の整数)。
* @param {number} startPointer - 開始インデックス(0以上の整数、範囲外は自動で丸め込み)。
* @param {(item:any, index:number)=>void} handle - 各要素を処理する関数(同期)。
* @returns {{ nextPointer: number, attempted: number, errors: Error[] }}
*/
function processBatch(queue, batchLimit, startPointer = 0, handle = (item) => void item) {
// 入力バリデーション(早期失敗で安全性を確保)
if (!Array.isArray(queue)) {
throw new TypeError('queue は配列である必要があります。');
}
if (!Number.isInteger(batchLimit) || batchLimit < 0) {
throw new TypeError('batchLimit は 0 以上の整数である必要があります。');
}
if (!Number.isInteger(startPointer) || startPointer < 0) {
throw new TypeError('startPointer は 0 以上の整数である必要があります。');
}
if (typeof handle !== 'function') {
throw new TypeError('handle は関数である必要があります。');
}
// 反復用ポインタ(開始位置は配列長を超えないように丸める)
let queuePointer = Math.min(startPointer, queue.length);
// 今回のバッチで試行した件数
let processedCount = 0;
// エラーを収集(必要に応じてロギング/監視システムへ送信)
const errors = [];
// ループ条件:
// - まだ未処理の要素が残っている(queuePointer < queue.length)
// - かつ、今回のバッチの上限に達していない(processedCount < batchLimit)
while (queuePointer < queue.length && processedCount < batchLimit) {
const item = queue[queuePointer];
try {
// 各要素の処理(同期)
// ここで例外が発生しても finally でポインタとカウントを進めるため無限ループになりません。
handle(item, queuePointer);
} catch (err) {
// 個別要素の失敗は収集して継続(バッチ全体は止めない)
errors.push(err instanceof Error ? err : new Error(String(err)));
} finally {
// 次の要素へ進む(試行件数も加算)
queuePointer += 1;
processedCount += 1;
}
}
return {
nextPointer: queuePointer, // 次回再開時の開始位置
attempted: processedCount, // 今回試行した件数(成功/失敗を含む)
errors, // 個別エラー一覧
};
}
// 使用例:
// const result = processBatch(myQueue, 100, 0, (item, index) => {
// // TODO: 各要素の処理ロジック
// });
循环逻辑:
变量作用:
退出条件:
用一句话概括:把“写 while 循环”这件高频又易出错的小事,交给专业提示词,省时、省心、更稳。