[Combine 开发] Controlling timing 时间控制

Combine框架里,关于时间控制大致有debounce、delay、measureInterval、throttle、timeout
下面我们分别介绍他们的区别和使用方法
值的我们注意的是Combine中的pipline是异步流,所以这些时间控制的Operator还是很强大的。
 

debounce

在某些情况下,我们可能会面临事件产生过于频繁的问题,比如用户输入的搜索关键字。如果我们在用户每次输入一个字符时都进行搜索,可能会导致不必要的网络请求。这时候,我们可以使用debounce来确保只有在用户停止输入一段时间后才进行搜索。 

let publisher = PassthroughSubject<Int, Never>()// 使用debounce操作符
let debounceCancellable = publisher.debounce(for: .seconds(3), scheduler: DispatchQueue.main).sink { value inprint("Debounce: \(value)")}publisher.send(1)
// 等待一段时间
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {publisher.send(2)
}
publisher.send(3)// 输出结果:
// Debounce: 2

 时间轴

  • 首先设置了时间窗口的时长,上图为3秒
  • publisher每次发送一个新的数据,都会重新开启一个时间窗口,并取消之前的时间窗口
  • 最后开启的时间窗口的时间结束后,如果没有新的数据,debounce把数据发送到下游

常见用例

  • 搜索框输入:如上例所示,确保在用户停止输入一段时间后再进行搜索,以减少网络请求次数。
  • 用户输入验证:在用户输入时,例如密码或用户名,使用debounce可以确保在用户停止输入后再执行验证,避免频繁的验证操作。
  • UI界面更新:在某些情况下,当界面上的某个状态发生变化时,使用debounce可以避免过于频繁地更新UI,提高性能。

delay 

在某些情况下,我们希望在接收到事件后等待一段时间再进行处理。例如,在用户点击一个按钮后,我们可能希望延迟一段时间再执行相应的操作,以提供更好的用户体验。

let publisher = PassthroughSubject<Int, Never>()// 使用debounce操作符
let debounceCancellable = publisher.delay(for: .seconds(3), scheduler: DispatchQueue.main).sink { value inprint("delay: \(value)")}publisher.send(1)
// 等待一段时间
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {publisher.send(2)
}
publisher.send(3)// 输出结果:
// delay: 1
// delay: 3
// delay: 2

 时间轴

  • 首先设置了时间窗口的时长,上图为3秒
  • 只有一个时间窗口,它能够让pipline在收到publisher发送的数据后,等待一定的时长,然后再发送数据到下游

常见用例

  • 搜索框输入:如上例所示,确保在用户停止输入一段时间后再进行搜索,以减少网络请求次数。
  • 用户输入验证:在用户输入时,例如密码或用户名,使用debounce可以确保在用户停止输入后再执行验证,避免频繁的验证操作。
  • UI界面更新:在某些情况下,当界面上的某个状态发生变化时,使用debounce可以避免过于频繁地更新UI,提高性能。

measureInterval 

在某些情况下,我们可能需要知道两个事件之间经过了多长时间,以便根据时间间隔执行不同的操作。例如,在用户进行某个操作后,我们可能希望在一段时间内等待,然后执行一些额外的逻辑。这时候,measureInterval就能派上用场。

private var cancellables: Set<AnyCancellable> = []
private var lastClickTime: Double = CFAbsoluteTimeGetCurrent()func simulateButtonClick() {Just(()).measureInterval(using: DispatchQueue.main).sink { timeInterval inprint(CFAbsoluteTimeGetCurrent() - lastClickTime)lastClickTime = CFAbsoluteTimeGetCurrent()}.store(in: &cancellables)
}simulateButtonClick()
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {simulateButtonClick()
}// 输出结果:
// 0.0002 
// 2.1025  

measureInterval它能够记录publisher发送数据的间隔时间

常见用例

  • 点击事件时间间隔监测:在用户点击按钮或进行其他交互时,使用measureInterval可以监测两次事件之间的时间间隔,从而触发不同的操作。
  • 用户活跃度追踪:记录用户活跃度并定期检查时间间隔,以执行相关的统计或分析。
  • 定时任务:测量两次定时任务触发之间的时间,以确保它们按照预期的间隔执行。

 timeout 

在异步操作中,有时我们希望在一定时间内得到结果,如果超时就认为操作失败。例如,网络请求超过一定时间没有响应,我们可能希望取消请求并提示用户。

enum MyError: Error {case timeout
}let publisher = PassthroughSubject<Int, Never>()// 使用debounce操作符
let cancellable = publisher.setFailureType(to: MyError.self).timeout(.seconds(1), scheduler: DispatchQueue.main,customError: { MyError.timeout }).sink(receiveCompletion: { error inswitch error {case .finished:print("finished")case .failure(let failure):print("failure: \(failure)")}}, receiveValue: { value inprint("send: \(value)")})publisher.send(1)等待一段时间
DispatchQueue.global().asyncAfter(deadline: .now() + 2) {publisher.send(2)
}// 输出结果:
// send: 1
// failure: timeout

 时间轴

  • 首先设置了时间窗口的时长,上图为1秒
  • publisher.timeout() 的时候,seconds(1)这个超时时间就已经开始计时,而不是从publisher.send开始计时
  • publisher每次发送一个新的数据,都会重新开启一个时间窗口(当然receiveCompletion执行了,整个pipline也就结束了)

常见用例

  • 网络请求超时处理:设置网络请求的超时时间,确保及时处理请求的超时情况。
  • 用户操作限时处理:在某些情况下,限定用户在一定时间内完成某个操作,超时则取消操作。
  • 定时任务:对于定时任务,可以使用timeout确保任务在规定时间内完成。

 

throttle

在某些情况下,我们可能希望限制事件的传递速率,以降低处理的频率。例如,在用户输入搜索关键字时,我们可能不希望每次输入都触发搜索请求,而是希望等待用户停止输入一段时间后再触发搜索。这时 throttle 操作符就派上用场了。

let publisher = PassthroughSubject<Int, Never>()// 使用throttle操作符
let cancellable = publisher.throttle(for: .seconds(6), scheduler: DispatchQueue.main, latest: true).sink { value inprint("Throttle: \(value)")}// 发送元素
publisher.send(1)
publisher.send(2) 
publisher.send(3)// 输出结果:
// Debounce: 3

 Parameters:

  • interval: 查找和发送最近的或第一个元素的时间间隔,用调度器的时间系统表示
  • scheduler: 发布元素的调度器 (publisher.send()调用的线程要和scheduler保持一致,且不能async, 否则会执行多遍)
  • latest: 布尔值,表示是否发布最新的元素。如果`false`, publisher会发出在间隔内接收到的第一个元素

常见用例

  • 搜索输入限制:在用户输入搜索关键字时,使用 throttle 以限制搜索请求的频率,提高性能。
  • UI界面更新:在某些情况下,限制 UI 界面更新的频率,以减少不必要的刷新。
  • 防抖处理:与搜索输入类似,防抖处理是一种限制触发频率的常见用例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627345.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用python实现文本/图片生成视频

使用Python来生成视频通常涉及到使用一些专门的库&#xff0c;比如 OpenCV 或者 moviepy。下面是一个简单的例子&#xff0c;使用OpenCV和PIL&#xff08;Python Imaging Library&#xff09;来创建一个视频。 python复制代码 import cv2 import numpy as np from PIL import …

【双指针】001移动零_C++

题目链接&#xff1a;移动零 目录 题目解析 代码书写 知识补充 题目解析 题目让我们求必须在不复制数组的情况下,编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 这题我们可以用双指针的方法来写&#xff1a; 我们这里将用两个数组下标来…

条码WMS仓储管理系统的价值与优势

在全球化和数字化的时代&#xff0c;企业面临着诸多挑战。在复杂的运营环境中&#xff0c;如何提高运营效率和效果&#xff0c;降低成本&#xff0c;增强竞争力&#xff0c;成为企业关注的焦点。而库存管理作为企业运营的关键环节&#xff0c;其重要性不言而喻。本文将深入探讨…

北交所交易手续费标准?哪家证券公司开通北交所券商交易手续费佣金万2?

北交所&#xff08;Beijing Exchange&#xff09;是指位于中国北京的一家金融交易所。北交所是中国政府为推动金融改革和国际化市场而设立的交易场所。它提供包括股票、债券、期货、外汇等多种金融产品的交易服务。北交所的目标是促进中国金融市场的发展&#xff0c;吸引国内外…

js forEach方法的使

JavaScript中的数组forEach()方法用于对数组中的每个元素执行指定的函数。该方法会遍历数组&#xff0c;并依次将每个元素传递给回调函数进行处理。forEach()方法不会改变原始数组&#xff0c;它只是用于遍历数组的一种方式。 forEach()方法的语法如下&#xff1a; array.for…

golang文件相对路径问题

目录结构 2.具体代码&#xff1a; const dataFile "../data/data.json"_, fileName, _, _ : runtime.Caller(1)dataPath : path.Join(path.Dir(fileName), dataFile)fmt.Println(dataPath)// open filefile, err : os.Open(dataPath)if err ! nil {log.Fatalln(err…

在IntelliJ IDEA中集成SSM项目

SSM项目&#xff1a;springMVC为控制器、spring 为事务层、 MyBatis 负责持久 首先看下集成后项目结构&#xff1a; 1、打开IntelliJ IDEA&#xff0c;点击 "File" -> "New" -> "Project"。 点击Finish&#xff0c;此时我们就已经创建了一…

postman自动化接口测试

背景描述 有一个项目要使用postman进行接口测试&#xff0c;接口所需参数有&#xff1a; appid: 应用标识&#xff1b;sign&#xff1a;请求签名&#xff0c;需要使用HMACSHA1加密算法计算&#xff0c;签名串是&#xff1a;{appid}${url}${stamp}&#xff1b;stamp&#xff1…

Idea如何重置免费使用30天

大家都知道&#xff0c;Idea的使用&#xff0c;不是免费的。需要自己购买&#xff0c;获取证书才能使用&#xff0c;那么怎么无限试用30天呢&#xff01;首次&#xff0c;自己点击 点击Evaluate按钮&#xff0c;就可以免费使用。 过了30天的试用期。重新试用30天。我们需要如下…

6-keto-PGF1α ELISA kit—ENZO LIFE SCIENCE

高灵敏ELISA试剂盒&#xff0c;3小时内可检测低至1.40 pg/ml 6-酮前列腺素F1α 6-酮-前列环素F1α&#xff08;6-keto-PGF1α&#xff09;是前列环素&#xff08;PGI2&#xff09;的稳定水解产物。由于前列环素在缓冲液中的半衰期很短&#xff08;2-3分钟&#xff09;&#xff…

vue2使用electron以及打包配置

1.创建项目 vue create vue-project 2.安装electron vue add electron-builder会自动安装相关依赖 安装成功后会在src下自动生成一个background.js文件就是相应的electron的配置信息 use strictimport { app, protocol, BrowserWindow } from electron import { createProto…

重启阿里云ESC服务器后,数据库与jar包外面无法访问bug

bug 重启了服务器&#xff0c;发现从外面无法连接数据库 原因 使用firewall-cmd --list-all命令查看服务器防火墙的配置&#xff0c;发现没有开启3306端口的开放&#xff0c;虽然我们在安全组设置3306端口但是防火墙没有开启&#xff0c;外面是依然无法访问的。 firewall-cm…

Python网络爬虫进阶:自动切换HTTP代理IP的应用

前言 当你决定做一个网络爬虫的时候&#xff0c;就意味着你要面对一个很大的挑战——IP池和中间件。这两个东西听起来很大上&#xff0c;但其实就是为了让你的爬虫不被封杀了。下面我就来给你讲讲如何搞定这些东西。 第一步&#xff1a;创建爬虫IP池的详细过程 首先&#xf…

ACM:每日学习 状压dp

状压dp&#xff1a; 状压dp是对一般dp的改进&#xff1a; //对于判断多种物品的取法&#xff0c;开多维数组比较麻烦&#xff0c;也不好开&#xff0c;使用二进制来表示物品的取与否。 //使用二进制的话&#xff0c;位运算就更能省时间了&#xff0c;而且更会节省空空间&…

[LitCTF 2023]easy_shark

解压缩&#xff0c;发现需要输入密码&#xff0c;使用010打开&#xff0c;发现frflags和deflags都被修改了&#xff0c;这就会造成压缩包伪加密 把他们都改为0&#xff0c;再打开 将流量包使用wirshark打开 过滤http&#xff0c;并追踪 得到以下信息 看到了一个类似于flag格…

文章阅读总结:多传感器融合:GNSS微弱信号场景的补救措施

[TOC](多传感器融合导航论文积累) # 知识点总结 ## 因子图 Factor Graph 是概率图的一种&#xff0c;是对函数因子分解的表示图&#xff0c;一般内含两种节点&#xff0c;变量节点和函数节点。 因子图存在着&#xff1a;**两类节点&#xff1a; 变量节点和对应的函数节点**变量…

4 - JdbcTemplate

spring 框架如何处理对数据库的操作呢? 1. 基本介绍 文档&#xff1a;JdbcTemplate APIs : /spring-framework-5.3.8/docs/javadoc-api/index.html JdbcTemplate 是 Spring 提供的访问数据库的技术。可以将 JDBC 的常用操作封装为模板方法 已经提供了特别多的 API 2. 使用…

Linux网络文件共享服务之FTP协议

目录 一、存储类型 1、直连式存储&#xff08;DAS&#xff09; 2、存储区域网络&#xff08;SAN&#xff09; 3、网络附加存储&#xff08;NAS&#xff09; 二、 FTP文件传输协议 1、FTP协议的工作原理 1.1 FTP协议的工作流程 1.2 FTP协议的两种工作模式 1.2.1 主动模…

flutter报错Cannot hit test a render box that has never been laid out

出现这个问题的原因可能是因为你把一个ListView或者GridView放到了一个没有设置大小的容器里面导致的&#xff0c;所以意思是不能渲染那一个没有布局过的容器。我这里遇到的错误是因为我把GridView放到了一个Container里面&#xff0c;并且我没有设置Container宽高。 就导致了那…

嵌入式工作岗位未来会不会越来越少?

今日话题&#xff0c;嵌入式工作岗位未来会不会越来越少&#xff1f;未来的嵌入式岗位机会将会逐渐增多&#xff0c;因为嵌入式技术是万物互联的基础&#xff0c;从智能手表到智能汽车&#xff0c;嵌入式都扮演着关键角色。虽然相比计算机科学CS&#xff0c;嵌入式领域的天花板…