RxJS与setTimeout组合使用出现意外运行行为问题求解
RxJS两段Observable创建代码发射时机差异原因
核心原因
这个差异和RxJS本身无关,是原生JS setTimeout API的参数规则导致的:setTimeout 第一个参数要求传入待延迟执行的函数引用,如果直接传入函数调用语句,JS会立即执行该语句,将返回值作为第一个参数传入,不会等待延迟时间。
两段代码的执行逻辑对比
第一段代码(符合预期)
内部setTimeout写法为:
setTimeout(()=>{ console.log("and now 5"); o.next(5)}, 1500)
- 第一个参数传入的是箭头函数的引用,没有立即执行
- 会等到1500ms延迟结束后才触发函数内部的
o.next(5),所以和前面的o.next(3)间隔1500ms发射
第二段代码(同时发射)
内部setTimeout写法为:
setTimeout(o.next(6), 1500)
- JS解析到这一行时就会立即执行
o.next(6),发射数值6 - 随后将
o.next(6)的返回值(默认undefined)传入setTimeout作为第一个参数,相当于执行了setTimeout(undefined, 1500),没有任何延迟执行的逻辑 - 所以
o.next(4)和o.next(6)会几乎同时触发,出现两个数值同时发射的现象
扩展提示
这种参数类型写错的问题是JS异步编程的常见坑,除了setTimeout/setInterval外,DOM事件监听、Promise回调、RxJS操作符回调等需要传入函数引用的场景,直接写函数调用语句都会触发立即执行的问题。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

