ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RxJS doWhile 操作符详解:用条件循环重复 Observable 序列

RxJS doWhile 操作符详解:用条件循环重复 Observable 序列 后端【免费下载链接】RxJSThe Reactive Extensions for JavaScript项目地址https://gitcode.com/gh_mirrors/rxj/RxJS点击查看免费下载导读doWhile是 RxJSReactive Extensions for JavaScript中用于按条件重复订阅并重新执行源 Observable的条件循环操作符它以函数式的方式模拟了传统命令式编程中的 do...while 循环。本文基于本仓库 doWhile 官方文档 展开结合 dowhile.js 源码、底层实现与 单元测试带你掌握doWhile的完整 API、内部原理、边界行为与实战写法读完即可在自己的流式逻辑中正确运用先执行一次、再按条件重复的循环语义。一、doWhile 是什么条件驱动的事件序列循环Rx.Observable.prototype.doWhile(condition)用于只要条件成立就重复执行源序列从而在响应式编程中模拟 do while 循环。它与传统while循环的关键差异在于源序列至少被执行一次然后才检查条件决定是否继续重复。这与本仓库另一个静态操作符Rx.Observable.while(condition, source)别名whileDo不同——while是先判断条件再执行而doWhile是先执行一次再判断条件两者互为补充Rx.Observable.while(condition, source)先判断条件为真才执行源序列observableProto.doWhile(condition)先执行当前源序列一次结束后判断条件条件为真则再次执行以此类推。从本仓库 while.js 源码 可以看到while的实现同时挂载了Observable[while]与Observable.whileDo两个入口其中whileDo是为 IE9 以下浏览器准备的别名var observableWhileDo Observable[while] Observable.whileDo function (condition, source) { isPromise(source) (source observableFromPromise(source)); return enumerableWhile(condition, source).concat(); };二、API 签名与参数说明2.1 方法签名Rx.Observable.prototype.doWhile(condition)2.2 参数参数类型说明conditionFunction决定源序列是否被重复执行的条件函数。源序列每次正常完成后都会调用它返回true则再次订阅并执行源序列返回false则终止循环并向观察者发出Completed。2.3 返回值doWhile返回一个新的Observable可观察序列。其观察者会随着条件循环的每次迭代多次接收到源序列中元素的通知。2.4 TypeScript 类型定义本仓库同时提供了 TypeScript 声明文件 ts/core/linq/observable/dowhile.ts签名为doWhile(condition: () boolean): ObservableT;可以看出条件函数是一个返回布尔值的无参回调返回值保持与源序列相同的元素类型T。三、官方示例先执行再判断的重复订阅以下是 doWhile 官方文档 中给出的完整示例。Rx.Observable.return(42)会产生一个只发出一次42后立即完成的序列doWhile中的条件i 2在第一次完成时返回truei从 0 自增到 1于是序列被重复执行第二次第二次完成时i已变为 2条件返回false循环终止并发出Completedvar i 0; var source Rx.Observable.return(42).doWhile(function (x) { return i 2; }); var subscription source.subscribe( function (x) { console.log(Next: %s, x); }, function (err) { console.log(Error: %s, err); }, function () { console.log(Completed); }); // Next: 42 // Next: 42 // Completed运行结果印证了 do...while 的语义先无条件执行一次输出第一个42再判断条件决定是否重复输出第二个42最后条件不满足发出Completed结束整个循环。四、源码级原理concat while 惰性枚举器4.1 doWhile 的极简实现doWhile的实现非常简洁位于 src/core/linq/observable/dowhile.jsobservableProto.doWhile function (condition) { return observableConcat([this, observableWhileDo(condition, this)]); };它等价于concat(当前源序列, Observable.while(condition, 当前源序列))。也就是说第一段this即当前源序列无条件执行一次第二段observableWhileDo(condition, this)即条件成立就重复执行的 while 序列紧跟在第一段之后拼接。由于concat会严格按顺序等待前一个序列完成后再订阅下一个因此整体效果正是先执行一次、条件成立再接着重复执行。4.2 while 序列的惰性枚举实现observableWhileDo的核心在 src/core/linq/enumerable/while.js它构建了一个WhileEnumerable惰性枚举器其迭代器每次调用next()时才求值条件函数WhileEnumerable.prototype[$iterator$] function () { var self this; return { next: function () { return self.c() ? { done: false, value: self.s } : { done: true, value: void 0 }; } }; };条件self.c()返回true产出{ done: false, value: source }表示还要再执行一次源序列条件返回false产出{ done: true }迭代结束concat也随之完成。这种按需求值的设计意味着条件函数只在上一轮源序列完成后才被调用不会提前执行也不会在订阅之前执行。4.3 concat 如何串联多次订阅从 src/core/perf/operators/concat.js 可以看到observableConcat会把多个序列包装为ConcatObservable逐个串行订阅、前一个完成后才订阅下一个。正是这一机制保证了doWhile的多轮重复是严格串行的——同一时刻最多只有一个源序列的订阅处于活跃状态每轮之间互不重叠。4.4 与静态Observable.while的等价性从实现上可以直接推断source.doWhile(condition)约等于source.concat(Rx.Observable.while(condition, source))。如果你只需要先判断后执行的循环语义可以直接使用静态方法Rx.Observable.while(condition, source)若需要至少执行一次的语义则应使用doWhile。五、边界行为与测试验证本仓库的单元测试 tests/observable/dowhile.js 使用TestScheduler对doWhile的各类边界行为做了系统验证是理解该操作符行为契约的最佳参考5.1 条件恒为 false只执行一次测试doWhile always falsetests/observable/dowhile.js#L13-L41条件始终返回false源序列在虚拟时间 200ms 处被订阅元素依次在 250/300/350/400ms 发出450ms 完成仅被订阅一次元素按原样透传后直接Completed。这正是 do...while 与 while 的核心区别即使条件一开始就为假源序列也会先执行一次。5.2 条件恒为 true无限重复测试doWhile always truetests/observable/dowhile.js#L43-L81展示了无限循环的形态源序列被反复重新订阅测试中 200–450、450–700、700–950、950–1000 共四轮订阅模拟时间到达 1000ms 时测试强制截断元素 1、2、3、4 依次循环出现。这是doWhile最重要的使用警示条件若永远返回true序列将无限循环下去永远不会发出Completed因此条件函数必须最终收敛为false。5.3 条件逐步收敛执行多轮后完成测试doWhile sometimes truetests/observable/dowhile.js#L129-L169是最典型的实用场景条件n 3在前两轮返回true、第三轮返回false结果源序列共被订阅 3 次200–450、450–700、700–950元素 1、2、3、4 完整出现三轮随后在 950ms 发出Completed。这与第一节官方示例的执行逻辑完全一致。5.4 源序列出错错误立即传播测试doWhile always true throwstests/observable/dowhile.js#L83-L105表明当源序列抛出错误时doWhile会立即将错误通过onError转发给下游观察者并终止循环不再继续重复。循环重复不会吞掉源序列的错误。5.5 条件函数抛出异常异常作为错误终止循环测试doWhile sometimes throwstests/observable/dowhile.js#L171-L217验证了条件函数自身抛错的场景当条件函数if (n 3) { return true; } else { throw error; }抛出异常时该异常被包装为onError通知测试断言 950ms 处收到onError(error)传给下游循环立即终止。这说明条件函数与普通回调一样遵循 RxJS 的异常即错误通知约定。六、实战建议与注意事项6.1 确保条件函数最终返回 falsedoWhile本身没有任何轮次上限一旦条件永远为真就是无界循环。建议在条件函数内部引入计数器、外部状态或时间边界例如i N、Date.now() deadline等保证循环可终止。若需要最多重复 N 次的语义也可以考虑与take(N)组合使用作为兜底保护。6.2 条件函数的求值时机根据 enumerable/while.js 的迭代器实现条件函数只在上一轮源序列正常完成之后才被调用且调用时不接收参数因此不要在条件函数中依赖本轮产生的元素值——它拿不到源序列发出的数据。若需要基于最新数据做决策应改用scan、takeWhile等基于元素的操作符。6.3 每一轮都是全新的订阅从测试的subscriptions断言可以看出doWhile的每一轮循环都会重新订阅源序列。这带来两个含义若源是Cold Observable如Rx.Observable.return、fromArray每一轮都会从头重新执行产生数据若源是Hot Observable如事件流或带副作用的序列重复订阅可能产生重复副作用需要自行评估是否可接受。6.4 与takeWhile/while的选型先执行后判断至少一次doWhile(condition)先判断后执行可能零次Rx.Observable.while(condition, source)别名whileDo见 src/core/linq/observable/while.js基于元素值终止takeWhile(predicate)它根据序列发出的每个元素决定是否继续与基于外部状态的条件循环语义不同。七、相关资源位置速查doWhile属于实验性Experimental功能集合相关文件在本仓库中的位置如下资源仓库路径官方 API 文档doc/api/core/operators/dowhile.md核心实现src/core/linq/observable/dowhile.jswhile 静态方法实现src/core/linq/observable/while.js惰性枚举器实现src/core/linq/enumerable/while.jsconcat 实现src/core/perf/operators/concat.jsTypeScript 类型声明ts/core/linq/observable/dowhile.ts单元测试tests/observable/dowhile.js该操作符被打包进rx.all.js、rx.all.compat.js与rx.experimental.js等发行版中使用前需确保已加载对应的前置基础文件rx.js/rx.compat.js/rx.lite.js/rx.lite.compat.js之一。通过对源码与测试的对照阅读你可以确认doWhile是一个语义精确、实现极简的条件循环操作符适合轮询重试、周期刷新等至少执行一次、按条件决定是否继续的流式场景。赞分享后端【免费下载链接】RxJSThe Reactive Extensions for JavaScript项目地址https://gitcode.com/gh_mirrors/rxj/RxJS点击查看免费下载相关推荐RxJS v4 Rx.Observable.while 操作符完全指南用条件驱动的循环式序列重复RxJS v4 Rx.Observable.while 操作符完全指南用条件驱动的循环式序列重复 Rx.Observable.while condition,后端RxJS v4 jortSort 操作符详解判断 Observable 序列是否已排序RxJS v4 jortSort 操作符详解判断 Observable 序列是否已排序 jortSort 是 RxJS v4Reactive Extensi后端Go QML与数据库集成数据驱动的GUI应用开发Go QML与数据库集成数据驱动的GUI应用开发 Go QML是一个为Go语言提供QML支持的开源项目它允许开发者使用Go语言的强大功能结合QML的现代UI后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表