Swift Combine — Future和Promise的使用

news2024/11/24 10:43:53

平时在开发的过程中,免不了进行异步编程,比如进行网络请求,以前异步编程的时候主要采用两种方法:

  1. 通过代理方法,设置代理,实现代理方法。
  2. 通过闭包block块处理。

采用第一种方法代码分家,不利于维护,有些时候方法名起不好都分辨不出来是内部方法还是代理方法。
采用第二种也有弊端,业务繁琐的话容易多层嵌套,再加上处理不同场景,那代码简直像一锅粥。

Combine提供的Future 大大简化了异步编程的代码,更利于维护,那么什么是Future呢?

引用官方的解释就是:

A publisher that eventually produces a single value and then finishes or fails.

首先是一个Publisher,发送单一的值,发送完以finish或者fails结束。Future代表将来,意在在将来的某个时间点发送数据给订阅者,多用在异步操作中。

final public class Future<Output, Failure> : Publisher where Failure : Error {

    /// A type that represents a closure to invoke in the future, when an element or error is available.
    ///
    /// The promise closure receives one parameter: a `Result` that contains either a single element published by a ``Future``, or an error.
    public typealias Promise = (Result<Output, Failure>) -> Void

    /// Creates a publisher that invokes a promise closure when the publisher emits an element.
    ///
    /// - Parameter attemptToFulfill: A ``Future/Promise`` that the publisher invokes when the publisher emits an element or terminates with an error.
    public init(_ attemptToFulfill: @escaping (@escaping Future<Output, Failure>.Promise) -> Void)

通过定义可知,创建Future实例的时候组要指定输出的类型和错误类型,在初始化方法中还要实现一个闭包,在闭包内返回一个Promise对象。
Promise对象也时候一个闭包,返回Result枚举类型(成功或者失败),Result所带的数据类型或者错误类型要和定义Future的类型保持一致。

我们可以通过初始化Future的闭包处理异步事件,然后将处理结果通过Promise发送出去。

初始化一个Future,并在闭包内返回Int类型的值。

let future = Future<Int, Never> { promise in
    promise(.success(1))
}

初始化一个Future,并在闭包内返回错误。

struct NetworkError: Error {}

let future = Future<Int, Error> { promise in
    promise(.failure(NetworkError()))
}

上面大概了解了FuturePromise,现在看看接下来这么用,Promise发出来一个事件值,那么就要有接收的人,也就是Subscriber

class FutureViewModel: ObservableObject {
  private var cancellable = Set<AnyCancellable>()

  func requestData() {
    let fetchFuture = Future<String, Never> { promise in
      DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 3) {
        promise(.success("Hello World"))
      }
    }
    
    fetchFuture
      .sink { completion in
        print("---> Received completion: \(completion)")
      } receiveValue: { value in
        print("---> Received value: \(value)")
      }
      .store(in: &cancellable)

    print("---> last line")
  }
}

FutureViewModel中定义了一个requestData方法,方法中创建了一个Future,并设置了类型,闭包内模拟请求网络数据的情况,3秒后发出获取成功事件,并带上获取到的数据。
随后通过sink方法添加了订阅者。

执行结果如下:
在这里插入图片描述
sink方法receiveValue闭包中收到了Promise发送的数值,并且接收到值后,执行了Completion闭包,结束事件流。

如果没有订阅者Subscriber,那么Promise发送出来的值就丢弃了,这和我们之前说的Publisher没有订阅者,那么发送的值就直接丢弃了一样。

最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

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

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

相关文章

eNSP学习——配置DHCP中继

目录 主要命令 原理概述 实验目的 实验内容 实验拓扑 实验编址 实验步骤 1、基本配置 2、搭建OSPF网络 3、配置DHCP服务器 4、配置DHCP中继 5、配置PC获取地址方式为DHCP 主要命令 //配置指定DHCP服务器的方法 //方法一&#xff1a;在面向PC的接口下直接配置DHCP服…

CentOS 7.9上创建的JBOD阵列恢复(二)

系列文章目录 CentOS 7.9上创建JBOD&#xff08;一&#xff09; CentOS 7.9检测硬盘坏区、实物定位&#xff08;三&#xff09; 文章目录 系列文章目录前言一、用命令查看是否认到盘二、直接组JBOD三、挂载到新目录四、查看原数据总结 前言 在CentOS 7.9上创建了一个软阵列JB…

游戏运营与发行:从入门到实践

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

数据中心分类和类别综合指南

数据中心可根据其规模、功能、所有权、层级和部署方法进行分类。以下是一些典型的数据中心类别和分类。 数据中心的分类和分级 根据尺寸 1. 小型数据中心&#xff1a;通常是为了满足对IT基础设施需求较少的组织或小型企业的需求而创建的。与大型数据中心相比&#xff0c;小型…

Redis缓存设计之常见问题及解决方案

背景&#xff1a;缓存的常见问题及对应的解决方案进行了整理&#xff0c;给大家分享一下。 1.缓存穿透 缓存穿透是指查询一个根本不存在的数据&#xff0c; 缓存层和存储层都不会命中&#xff0c; 通常出于容错的考虑&#xff0c; 如果从存储 层查不到数据则不写入缓存层。 缓…

【深度学习】GPT-3,Language Models are Few-Shot Learners(一)

论文&#xff1a; https://arxiv.org/abs/2005.14165 摘要 最近的研究表明&#xff0c;通过在大规模文本语料库上进行预训练&#xff0c;然后在特定任务上进行微调&#xff0c;可以在许多NLP任务和基准上取得显著的进展。虽然这种方法在结构上通常是任务无关的&#xff0c;但…

国内外LabVIEW开发的区别

​分析国内外在LabVIEW开发中的差异需要从多个方面进行比较&#xff0c;包括界面设计、架构设计、注释与文档、调试方法、维护策略以及升级与迭代管理等。 界面设计&#xff1a; 国外的LabVIEW界面设计通常更加注重用户体验和视觉美观&#xff0c;使用现代化的控件和布局&…

基于ResNet-18的简单分类(新手,而且网络效果不咋滴,就是学个流程)

引言 先看问题&#xff1a; 我手边有一数据集&#xff0c;然后我想分分类&#xff01;~~ 咳咳&#xff0c;最近刚做了一个&#xff1a;训练集有1143张&#xff0c;分为5类&#xff0c;里面图片是打乱的。测试集有248张&#xff0c;想把它分分类看看咋样。 再看一下效果: …

mellanox HCA IB网卡固件更新

注意事项&#xff1a; 1.如果PSID以SGN开头&#xff0c;说明该产品是曙光的OEM产品&#xff0c;可以向HPC高速网络部获取固件。如果PSID以MT开头&#xff0c;说明该产品是Mellanox或nvidia的标准产品&#xff0c;可以通过官网下载固件。 2.通过官网获取固件&#xff0c;一定要…

Nginx缓存之web缓存配置

Web 缓存可节约网络带宽&#xff0c;有效提高用户打开网站的速度。由于应用服务器被请求次数的降低&#xff0c;也相对使它的稳定性得到了提升。Web 缓存从数据内容传输的方向分为前向位置缓存和反向位置缓存两类。如下图所示。 前向位置缓存既可以是用户的客户端浏览器&#x…

【免费API推荐】:轻松集成,为您的应用增添更多价值(9)

开发者喜爱的免费API是他们在开发过程中最宝贵的伙伴。这些API提供了丰富的功能和数据&#xff0c;帮助开发者构建出令人惊叹的应用。无论是地图服务、社交媒体集成、数据分析还是人工智能&#xff0c;这些免费API为开发者提供了强大的工具和资源&#xff0c;让他们能够更轻松地…

任务4.8.3 利用SparkSQL统计每日新增用户

实战概述&#xff1a;利用SparkSQL统计每日新增用户 任务背景 在大数据时代&#xff0c;快速准确地统计每日新增用户是数据分析和业务决策的重要部分。本任务旨在使用Apache SparkSQL处理用户访问历史数据&#xff0c;以统计每日新增用户数量。 任务目标 处理用户访问历史数…

兴业法拍网周报|在北京你是选择租房还是买房?(6.10-6.14)

西城区金融世家10号楼6单元801、803&#xff08;共两套&#xff09; 位置优越:金融世家所在区域位于国家政治中心和国家金融管理中心&#xff0c;是凝集国家“政经”的焦点。临近长安街、金融街、西二环交通动脉&#xff0c;道路通畅便捷&#xff0c;保值率高。 优质教资:附近…

Objective-C 学习笔记 | KVO(key-value obsereving)

Objective-C 学习笔记 | KVO&#xff08;key-value obsereving&#xff09; Objective-C 学习笔记 | KVO&#xff08;key-value obsereving&#xff09;使用 KVOKVO 的工作原理 Objective-C 学习笔记 | KVO&#xff08;key-value obsereving&#xff09; KVO 是指当指定的对象…

如何掌握 Java 中的国际化和本地化

随着全球化的发展&#xff0c;软件开发不仅要满足本地用户的需求&#xff0c;还要满足全球用户的需求。因此&#xff0c;软件的国际化&#xff08;Internationalization&#xff0c;I18N&#xff09;和本地化&#xff08;Localization&#xff0c;L10N&#xff09;显得尤为重要…

为什么网上这么多破解 Intellij IDEA 的工具,但是官方却不管呢?

大家好&#xff0c;我是小2&#xff0c;一个程序员~ 程序员小2 每天一篇技术重磅好文&#xff0c;涉及一线互联网大厂应用架构&#xff08;高可用、高性能、高稳定&#xff09;&#xff0c;AI、大数据、java架构等热门领域。 112篇原创内容 公众号 来源&#xff1a;Java知音…

【代码随想录——动态规划——第五周】

1.单词拆分 func wordBreak(s string, wordDict []string) bool {n : len(s)dp : make([]bool, n1)dp[0] truefor j : 0; j < len(wordDict); j {if len(wordDict[j]) > n {continue}if wordDict[j] s[:len(wordDict[j])] {dp[len(wordDict[j])] true}}//fmt.Println(…

Facebook与地方文化:数字平台的多元表达

在当今数字化时代&#xff0c;社交媒体不仅仅是人们交流的工具&#xff0c;更是促进地方文化传播和表达的重要平台。作为全球最大的社交网络之一&#xff0c;Facebook在连接世界各地用户的同时&#xff0c;也成为了地方文化多元表达的重要舞台。本文将深入探讨Facebook如何通过…

简单通用防篡改水印组件封装(vue3)

一、项目结构 二、项目代码 1.App.vue <template><div class"container"><Watermark text"版权所有"><div class"content"></div></Watermark><Watermark text"禁止转载" style"backgr…

【MongoDB 新搭档 Kafka】

对于做过数据处理&#xff0c;使用过消息队列的小伙伴 &#xff0c;Kafka可以算是老朋友了&#xff0c;但是最近一个场景下&#xff0c;新的用法&#xff0c;让其变为了MongoDB的新搭档。 开始 从一个问题开始&#xff0c;熟悉MongoDB的小伙伴&#xff0c;可能使用过changeSt…