
es-toolkit 的every用 pipe 对迭代器做全量条件校验的终端操作【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkitevery是 es-toolkit 为 JavaScript 迭代器提供的一个函数式编程工具它以(value, index) unknown形式的谓词为参数返回一个消费迭代器并判断「所有元素是否都满足条件」的函数专用于函数式组合管线 pipe。阅读本文后你将掌握es-toolkit/fp/iterator中every的调用签名、短路语义、与原生Iterator.prototype.every的取舍以及它在惰性管道中与无限序列协同工作的底层原理。背景es-toolkit/fp/iterator与pipeevery定义在 src/fp/iterator/every.ts属于 es-toolkit 的迭代器模块。整个es-toolkit/fp/iterator模块导出清单见 src/fp/iterator/index.ts把所有操作都以**柯里化数据后置**形式提供给 pipe 使用例如map、filter、take、drop、chunk、scan、toArray、reduce、some以及本文主角every。这些操作的基础是惰性求值与es-toolkit/iterator一样管道按元素逐个处理而不是每一步都构造中间数组详见 es-toolkit/iterator 介绍。every在其中扮演的是终端操作terminal step——它位于管道的末尾把整个管道收敛为一个布尔值const result pipe(source, every(predicate));核心语义消费迭代器并判断「是否全部满足」every会持续消费传入的迭代器直到predicate返回一个假值falsy为止并报告「是否所有元素都匹配了条件」。由于它遇到第一个不匹配的元素就会停止拉取stop pulling因此只要出现一个不满足条件的元素即使是无限迭代器也能正常终止。在内部every将判定逻辑委托给原生的Iterator.prototype.every执行源码见 src/fp/iterator/every.tsexport function everyT(predicate: (value: T, index: number) unknown): (source: IteratorT) boolean { return function everyInIterator(source: IteratorT): boolean { return Iterator.from(source).every(predicate); }; }也就是说es-toolkit 的every本身并不重写判定算法而是借助Iterator.from把任意迭代器统一包装成带有原生迭代器助手方法的IteratorObject再调用原生every——这正是它能够正确处理Map/Set迭代器、生成器函数返回值等各种来源的原因。基本用法import { pipe } from es-toolkit/fp; import { every } from es-toolkit/fp/iterator; // 所有元素都是偶数。 pipe( [2, 4, 6].values(), every(x x % 2 0) ); // 结果: true // 遇到第一个奇数即停止。 pipe( [2, 3, 4].values(), every(x x % 2 0) ); // 结果: false参数说明predicate(value: T, index: number) unknown对每个元素连同其索引调用一旦返回假值判定立即短路为false。返回值(source: IteratorT) boolean一个消费迭代器并返回「是否所有元素都满足条件」的函数。与原生Iterator.prototype.every如何选择值得注意的是es-toolkit 文档明确指出在不需要 pipe 组合的普通代码中优先使用原生 APIsource.every(predicate);只有当你需要通过pipe串联变换如先filter再map再every时才使用es-toolkit/fp/iterator版本的every。它存在的意义是提供「数据后置、可插入管道」的柯里化形态而非取代原生的迭代器助手。短路与惰性在管道中如何提前终止every的短路行为由原生Iterator.prototype.every保证第一个假值返回后不再拉取后续元素。这一特性在管道中有两层意义对有限序列遇到第一个不匹配元素即返回falsepredicate不会被多余调用适合对「前置条件校验」这类场景做快速失败。对无限序列只要序列中确实存在不匹配元素every就能在有穷步内完成不会因无限生成而挂起。es-toolkit 迭代器的惰性与提前终止还建立在底层的迭代器关闭协议之上。内部辅助函数 src/iterator/_internal/iterator.ts 展示了这一设计它手工实现next而非使用生成器注释中提到直接驱动迭代器协议比基于yield的生成器约快一倍并保证当消费者提前终止例如for...of中break、take达到上限、回调抛异常时通过return方法精确执行一次onClose从而释放上游资源如生成器里的try/finally清理逻辑。在pipe层面src/fp/pipe.ts 会把连续出现的惰性函数分组成单个短路的遍历过程lazyPipe而every作为终端步骤位于分组末尾最终只消费「必须被检查」的那部分元素其余输入不会被访问。与some的对照every有一个天然的对偶操作somesome在第一个真值返回时短路为true实现于 src/fp/iterator/some.ts其结构完全对称——同样返回Iterator.from(source).some(predicate)。操作短路条件返回true的情形everypredicate 返回假值所有元素都满足条件somepredicate 返回真值至少一个元素满足条件二者均委托原生Iterator.prototype的对应方法可视为管道形态下「全称/存在」判定的两个终端选择。在真实管道中与其他算子组合every常与filter、map、take等变换算子协同使用先对迭代器做惰性变换再做整体判定。仓库中的单元测试见 src/fp/iterator/index.spec.ts覆盖了包括every在内的一批终端操作例如import { pipe } from ../pipe.ts; import { every } from ./index.ts; pipe( [2, 4, 6].values(), every(x x % 2 0) ); // true一个更贴近实战的组合示例——校验「所有经过过滤后的元素都满足阈值」import { pipe } from es-toolkit/fp; import { filter, every } from es-toolkit/fp/iterator; const source [3, 6, 9, 12, 15].values(); const allBigEnough pipe( source, filter(x x % 3 0), every(x x 6) ); // true3 被过滤掉其余均 6使用注意事项迭代器只能消费一次与所有 JavaScript 迭代器一致被every消费后的迭代器不再产生任何元素这是Iterator.from包装对象的固有行为不要试图复用它。空迭代器返回true由于不存在不满足条件的元素空序列上every的结果是true这与原生Iterator.prototype.every及数组Array.prototype.every的语义一致。导入路径请从es-toolkit/fp导入pipe从es-toolkit/fp/iterator导入every二者缺一不可。延伸阅读pipe 函数参考函数式组合管线的入口与惰性融合机制es-toolkit/iterator 介绍迭代器模块的惰性求值、无限序列与一次性消费设计迭代器模块参考索引chunk、scan、takeWhile、zip等更多迭代器操作源码src/fp/iterator/every.ts、src/fp/iterator/some.ts、src/fp/iterator/index.ts、src/fp/pipe.ts、src/iterator/_internal/iterator.ts测试src/fp/iterator/index.spec.ts【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考