golang 函数式编程库samber/mo使用: Future

golang 函数式编程库samber/mo使用: Future

如果您对samber/mo库不了解, 请先阅读第一篇 Option

本节讲述Future的使用,它可以帮助我们处理异步编程问题。

示例

我们先来看看下面代码的示例, 注释解释了每一步的操作。

package mainimport ("fmt""github.com/samber/mo"
)func main() {// resolve 在这里只是一个定义, NewFuture会以一个 goroutine 的方式执行 cb, 并且传递Future 的 resolve 和 rejectvalue, err := mo.NewFuture(func(resolve func(string), reject func(error)) {// do something hereif true { // 这里假定 do something 成功// 如果 do something 成功, 执行 resolve, 并传递一个值, 然后会执行 Thenresolve("foobar")} else {// 告诉 do something 失败, 执行 reject, 并传递一个错误, 然后会执行 Catchreject(fmt.Errorf("failure"))}}).Then(func(s string) (string, error) {// 这里 s 就是 resolve 传递的值return s, nil}).Catch(func(err error) (string, error) {// 这里 err 就是 reject 传递的错误return "foobar", nil}).Finally(func(value string, err error) (string, error) {// 不管发生什么都会执行, value 是 resolve 传递的值, err 是 reject 传递的错误return value, nil}).Collect() // 等待 future 执行完毕, 并返回最终的值fmt.Println(value)fmt.Println(err)// Output:// foobar// <nil>
}

源码解析

根据mo.NewFuture的实现, 可以看出该函数做的事情就是构造一个Future, 然后执行activate函数, activate实际就是用 goroutine 执行cb函数, 并且将 Future 的 resolve 和 reject函数作为参数传递给cb

func NewFuture[T any](cb func(resolve func(T), reject func(error))) *Future[T] {future := Future[T]{cb:       cb,cancelCb: func() {},done:     make(chan struct{}),}future.active()return &future
}func (f *Future[T]) active() {go f.cb(f.resolve, f.reject)
}

resolve的实现如下, 可以看到resolve做的事情就是用mo.OK包装value, 记录到result中,并且关闭f.done, 表明future已经完成。

resolve加锁的目的是为了确保后续Then或Finally不会同时进行。

func (f *Future[T]) resolve(value T) {f.mu.Lock()defer f.mu.Unlock()f.result = Ok(value)if f.next != nil { // 这里如果不为空,表明next先于something注册,需要执行f.next.activeSync()}close(f.done)
}

我们来看看Then的实现,这个函数先对f执行加锁, 然后构造一个新的Future,这个新的Future的cb函数就是为了判断f的执行结果, 如果f的result不是error, 就执行Then注册的回调 cb。 所以如果f.cb函数执行resolve后返回, f.result.IsError()为false, 会执行Then中的回调。

最后的select表示如果f已完成,用goroutine 执行Then中的回调。如果f还没有完成,则留待f.cb的resolve或reject执行Then的回调。两种情况都会直接返回f.next,不会阻塞。这样就实现了Future的串联。

func (f *Future[T]) Then(cb func(T) (T, error)) *Future[T] {f.mu.Lock()defer f.mu.Unlock()f.next = &Future[T]{cb: func(resolve func(T), reject func(error)) {if f.result.IsError() {reject(f.result.Error())return}newValue, err := cb(f.result.MustGet())if err != nil {reject(err)return}resolve(newValue)},cancelCb: func() {f.Cancel()},done: make(chan struct{}),}select {case <-f.done:f.next.active()default:}return f.next
}

CatchThen的区别是如果f.result是error, 就执行Catch中的回调。Finally是不管f.result是什么, 都会执行Finally中的回调。

最后的Collect是用于等待Future执行完毕, 并返回最终的值。

func (f *Future[T]) Collect() (T, error) {<-f.donereturn f.result.Get()
}

还有 ResultEither方法, 用于获取Future的执行结果, 会阻塞直到Future执行完毕(也就是先执行Collect)

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

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

相关文章

深度学习 精选笔记(5)多层感知机

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

spring自定义事件监听器

1. 创建自定义事件 import org.springframework.context.ApplicationEvent; import java.util.List;public class CollectionCreateEvent extends ApplicationEvent {private List<String> fileList;public CollectionCreateEvent(Object source,List<String> file…

vscode——本地配置(C和C++环境配置)(2)

vscode——本地配置&#xff08;2&#xff09; 配置C语言编译看看.json文件编译多个C文件C/C调试 今天我们继续来看vscode的配置&#xff0c;如果没看过上一次的文章&#xff0c;大家可以点击&#xff1a; https://blog.csdn.net/qq_67693066/article/details/136315696 配置C语…

【漏洞复现】鸿运(通天星CMSV6车载)主动安全监控云平台存在敏感信息泄露漏

漏洞描述 鸿运(通天星CMSV6车载)主动安全监控云平台实现对计算资源、存储资源、网络资源、云应用服务进行7*24小时全时区、多地域、全方位、立体式、智能化的IT运维监控,保障IT系统安全、稳定、可靠运行。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法…

【Spring连载】使用Spring Data访问 MongoDB----Aggregation Framework支持

【Spring连载】使用Spring Data访问 MongoDB----聚合框架支持 一、基础槪念二、投影表达式Projection Expressions三、分面分类法Faceted Classification3.1 桶Buckets3.2 多方面的聚合Multi-faceted Aggregation3.3 按计数排序Sort By Count3.4 投影表达式中的Spring表达式支持…

leetcode 3.反转链表;

1.题目&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 2.用例&#xff1a; 3.题目解析&#xff1a; &#xff08;1&#xff09;函数头&#xff1a; 要求返回结点&#xff0c;就 ListNode* reverseList(ListNode* head)&…

海量物理刚体 高性能物理引擎Unity Physics和Havok Physics的简单性能对比

之前的博客中我们为了绕过ECS架构&#xff0c;相当于单独用Batch Renderer Group实现了一个精简版的Entities Graphics&#xff0c;又使用Jobs版RVO2实现了10w人同屏避障移动。 万人同屏对抗割草 性能测试 PC 手机端 性能表现 弹幕游戏 海量单位同屏渲染 锁敌 避障 非ECS 那么有…

Android Activity启动模式

文章目录 Android Activity启动模式概述四种启动模式Intent标记二者区别 Android Activity启动模式 概述 Activity 的管理方式是任务栈。栈是先进后出的结构。 四种启动模式 启动模式说明适用场景standard标准模式默认模式&#xff0c;每次启动Activity都会创建一个新的Act…

數據集成平台:datax將MySQL數據以query方式同步到hive

數據集成平台&#xff1a;datax將MySQL數據以query方式同步到hive 1.py腳本 # codingutf-8 import json import getopt import os import sys import MySQLdb import re# MySQL相关配置&#xff0c;需根据实际情况作出修改 mysql_host "xx" mysql_port "330…

最新IE跳转Edge浏览器解决办法(2024.2.26)

最新IE跳转Edge浏览器解决办法&#xff08;2024.2.26&#xff09; 1. IE跳转原因1.1. 原先解决办法1.2. 最新解决办法1.3. 最后 1. IE跳转原因 关于IE跳转问题是由于在2023年2月14日&#xff0c;微软正式告别IE浏览器&#xff0c;导致很多使用Windows10系统的电脑在打开IE浏览…

iOS 通过NSURLProtocol拦截WKWebView网络请求

以前NSURLProtocol可以直接拦截UIWebView&#xff0c;后面升级成WKWebView发现拦截不到了 有细心爱研究的老铁发现了 [WKBrowsingContextController registerSchemeForCustomProtocol:] 这个函数的存在 所以还是可以拦截的 直接上步骤 1.在控制器或者你喜欢的地方注册NSU…

kubectl 声明式资源管理方式

目录 介绍 YAML 语法格式 命令 应用yaml文件指定的资源 删除yaml文件指定的资源 查看资源的yaml格式信息 查看yaml文件字段说明 查看 api 资源版本标签 修改yaml文件指定的资源 离线修改 在线修改 编写yaml文件 创建资源对象 查看创建的pod资源 创建service服务对…

【蓝牙协议栈】【BR/EDR】【AVRCP】蓝牙音视频远程控制协议

1. AVRCP概念 AVRCP(Audio/Video Remote Control Profile):音视频远程控制协议定义了蓝牙设备和 audio/video控制功能通信的特点和过程,另用于远程控制音视频设备,底层传输基于 AVCTP(音视频控制传输协议)。 ➢该 Profile定义了AV/C数字命令控制集。命令和信息通过 AVCT…

虚拟机CentOS7仓库被禁用无法进行yum命令

执行yum repolist all命令时&#xff0c;仓库全被禁用 使用sudo yum-config-manager --enable C7.5.1804-base/x86_64去尝试启用其中的仓库时没反应 通过ls /etc/yum.repos.d/命令发现 [rootlocalhost ~]# ls /etc/yum.repos.d/ CentOS-Base.repo.bak CentOS-fasttrack.repo Ce…

博途PLC 单通气缸功能块(SCL源代码)

气缸是工业现场应用非常多的一个重要执行器,气缸在很多场合都有大量应用,今天我们的对象就是"单通气缸",不同的工程师,不同的应用行业,大家对气缸功能块的封装会有所不同。气缸功能块的其它封装大家可以参看下面文章 1、气缸功能块 https://rxxw-control.blog…

设计模式-桥接模式(C++)

C中可以通过使用抽象类和接口来实现桥接模式。桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。 在C中实现桥接模式的步骤如下&#xff1a; 1. 定义抽象类&#xff08;或接口&#xff09;&#xff1a;首先&#xff0c…

Flutter(三):Stack、Positioned、屏幕相关尺寸、Navigator路由跳转

页面尺寸 通知栏高度&#xff1a;MediaQuery.of(context).padding.top顶部导航高度&#xff1a;kToolbarHeight底部导航高度&#xff1a;kBottomNavigationBarHeight屏幕宽&#xff1a;MediaQuery.of(context).size.width屏幕高&#xff1a;MediaQuery.of(context).size.height…

拉美巴西阿根廷媒体宣发稿墨西哥哥伦比亚新闻营销如何助推跨境出海推广?

【本篇由言同数字科技有限公司原创】拉美地区是一个巨大的市场&#xff0c;其中包括了许多国家&#xff0c;如巴西、阿根廷、智利、哥伦比亚等。这些国家的消费者对品牌的认知度和忠诚度不同&#xff0c;而且市场环境也存在着很大的差异。因此&#xff0c;品牌需要通过跨境海外…

RTCA DO-178C 机载系统和设备认证中的软件注意事项-软件质量保证流程(八)

8.0 软件质量保证流程 SOFTWARE QUALITY ASSURANCE PROCESS 本节讨论软件质量保证 (SQA) 过程的目标和活动。 SQA 流程按照软件规划流程&#xff08;参见 4&#xff09;和软件质量保证计划&#xff08;参见 11.5&#xff09;的定义进行应用。 SQA 过程活动的输出记录在软件质量…

【计算机】本科考研还是就业?

其实现在很多计算机专业的学生考研&#xff0c;也是无奈的选择 技术发展日新月异&#xff0c;而在本科阶段&#xff0c;大家学着落后的技术&#xff0c;出来找工作自然会碰壁。而且现在用人单位的门槛越来越高&#xff0c;学历默认研究生起步&#xff0c;面试一般都是三轮起步…