DispatchGroup 逻辑工作流程

2023-11-30

我正在尝试实施DispatchGroup如下,但如果第一个调用返回true,然后第二个返回false,那么总体结果将返回false.

但是,如果第一个调用返回false,然后第二个返回true,那么总体结果将返回false这不是我所期望的。

我想回来false,如果任何调用返回false。我怎样才能处理这个问题?

 func storeInformation(id: String?, _ completion: @escaping (Bool) -> ()) {
    guard
      let id =  id
    else {
      completion(false)
      return
    }
    let dispatchGroup = DispatchGroup()
    var groupResult: Bool = false
    dispatchGroup.enter()
    storeFeatures { success in
      if success {
        groupResult = true
      } else {
        groupResult = false
      }
      dispatchGroup.leave()
    }
    
    dispatchGroup.enter()
    storeClasses { success in
      if success {
        groupResult = true
      } else {
        groupResult = false
      }
      dispatchGroup.leave()
    }
    dispatchGroup.notify(queue: .main) {
      completion(groupResult)
    }
  }

  private func storeClasses(_ completion: @escaping(Bool) -> Void) {
    postClasses { (error) in
      if let _ = error {
        completion(false)
      } else {
        completion(true)
      }
    }
  }

  private func storeFeatures(_ completion: @escaping(Bool) -> Void) {
    postFeatures { (error) in
      if let _ = error {
        completion(false)
      } else {
        completion(true)
      }
    }
  }

如果我们看看你的storeClasses and storeFeatures,我们看到他们是not真正返回 Bool 的操作;他们本质上是试图发布一些东西可能会失败。因此你真正想知道的不是东西是否返回true or false但无论是否failed。这就是你真正的意思——在编程中,最好说出你的意思.

使用组合框架,我们可以以令人难以置信的简洁来表达这种行为。当我们要同时执行多个异步操作时,这就是合并。如果其中一个失败了整个合并失败。换句话说,你想做的事情实际上是自动的!

例如,想象一下,我们通过将您的后期操作包装在延迟的 Futures 类型中来表达它们<Void,Error>。假设我们有方法storeClassesFuture and storeFeaturesFuture产生这些期货。那么你所要说的就是:

Publishers.Merge(storeClassesFuture(), storeFeaturesFuture())

这就是它的全部内容!如果您订阅了该合并sink,那么它要么收到一个finished完成或failure完成。你猜怎么着?它接收到failure完成当且仅当一个或两个后操作失败!它接收到finished仅当他们都成功时才完成,即exactly你想知道什么。

作为测试台,这里是您的示例实现storeInformation(出于示例的目的,我忽略了字符串):

var storage = Set<AnyCancellable>()
enum Oops : Error { case darn }
func storeInformation() {
    Publishers.Merge(storeClassesFuture(), storeFeaturesFuture())
        .receive(on: DispatchQueue.main)
        .sink { (completion) in
            switch completion {
            case .failure: print("at least one of them failed")
            case .finished: print("they both succeeded")
            }
            print("---")
        } receiveValue: { _ in }
        .store(in: &storage)
}

作为随机测试,这里有两个可以随机成功或失败的 future:

func storeClassesFuture() -> AnyPublisher<Void,Error> {
    Deferred {
        Future<Void,Error> { promise in
            if Bool.random() {
                print("storeClassesFuture succeeded")
                promise(.success(()))
            } else {
                print("storeClassesFuture failed")
                promise(.failure(Oops.darn))
            }
        }
    }.eraseToAnyPublisher()
}
func storeFeaturesFuture() -> AnyPublisher<Void,Error> {
    Deferred {
        Future<Void,Error> { promise in
            if Bool.random() {
                print("storeFeaturesFuture succeeded")
                promise(.success(()))
            } else {
                print("storeFeaturesFuture failed")
                promise(.failure(Oops.darn))
            }
        }
    }.eraseToAnyPublisher()
}

这是调用的一些示例输出storeInformation反复:

storeClassesFuture succeeded
storeFeaturesFuture succeeded
they both succeeded
---
storeClassesFuture failed
storeFeaturesFuture failed
at least one of them failed
---
storeClassesFuture failed
storeFeaturesFuture succeeded
at least one of them failed
---
storeClassesFuture failed
storeFeaturesFuture failed
at least one of them failed
---
storeClassesFuture failed
storeFeaturesFuture succeeded
at least one of them failed
---
storeClassesFuture succeeded
storeFeaturesFuture succeeded
they both succeeded
---
storeClassesFuture succeeded
storeFeaturesFuture succeeded
they both succeeded
---
storeClassesFuture failed
storeFeaturesFuture succeeded
at least one of them failed
---
storeClassesFuture failed
storeFeaturesFuture succeeded
at least one of them failed
---
storeClassesFuture succeeded
storeFeaturesFuture succeeded
they both succeeded
---

正如您所看到的,您所追求的逻辑通过两个可失败的 Future 的合并完美地表达了。

(这种事情是采用Combine框架而不是使用DispatchGroup的一个很好的理由。我发现我以前用DispatchGroup做的所有事情都可以用Combine做得更好。这恰好是一个特别明确的实例。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DispatchGroup 逻辑工作流程 的相关文章

  • 如何在 iOS 上的视图之间进行展开/收缩转换?

    我正在尝试在 iOS 中制作过渡动画 其中视图或视图控制器似乎扩展以填充整个屏幕 然后在完成后收缩回原来的位置 我不确定这种类型的转换的正式名称是什么 但您可以在 iPad 版 YouTube 应用中查看示例 当您点击网格上的搜索结果缩略图
  • iOS 显示 UIImage 全屏并启用缩放(捏合和双击)

    我有一个UIImage从相机捕获UIImagePickerController 现在 在用户单击它之后 我希望它显示全屏 并且能够使用捏合手势进行放大和缩小 还可以使用双击手势来放大特定区域 换句话说 我想模拟ios默认图像浏览器的功能 我
  • 使 Swift 类符合需要 init 的协议

    我有以下内容protocol in Swift protocol FooConvertible typealias FooType init foo FooType 我会做Swift类在类定义中符合它 class Bar FooConver
  • 应用程序需要很长时间才能同步线程(或根本不同步)

    我在 Delphi XE5 iOS 和 Android 中使用 REST 组件 我目前正在通过 iOS 模拟器进行测试 我的应用程序often挂在我的代码中的以下行 R Request Execute 经过一些调试后 我发现它特别挂在 RE
  • 更新到 Xcode 7.0.1,项目现在有问题

    因此 我将 Xcode 6 1 版本上传到 iTunes Connect 并且该应用程序获得了批准 现在我正在尝试更新应用程序 我更新到 Xcode 7 0 1 Xcode 给我带来了问题 指出 对于应用程序 我使用了故事板和 Object
  • iOS 新手。预期的表达错误?

    这看起来很不寻常 因为该方法与我的 showAnswer 方法完全相同 所以我想我应该在这里问 import QuizViewController h interface QuizViewController end implementat
  • Java中RandomAccessFile的并发

    我正在创建一个RandomAccessFile对象通过多个线程写入文件 在 SSD 上 每个线程都尝试在文件中的特定位置写入直接字节缓冲区 并且我确保线程写入的位置不会与另一个线程重叠 file getChannel write buffe
  • 托管线程多久切换一次操作系统线程?

    据我所知 托管线程不能保证在同一操作系统线程上运行 如果 CLR 可以在操作系统线程之间切换托管线程 这种情况发生的频率是多少 频率受什么影响 我有一个单独的问题 https stackoverflow com questions 1979
  • 使用捏合手势;如何放大用户手指实际“捏”的位置?

    我已经在我的应用程序中的 UIImageView 上实现了 UIPinchGestureRecognizer 但是无论我在图像的哪个位置捏合 它似乎都会放大到同一个位置 有谁知道我如何让它放大到用户实际 捏 的地方 请参阅下面的代码 视图控
  • 在 swift 中获取用户可读的类名版本(在 objc NSStringFromClass 中就可以了)

    Swift 中是否有相当于 NSStringFromClass 的类名 可以提供用户可读的版本 我尝试将它与我创建的本机 Swift 类一起使用 但如您所见 结果似乎是编译器对类名的内部表示 println NSStringFromClas
  • 未安装的应用程序的URL方案

    简单的问题 我正在开发一个将注册自己的 URL 方案的应用程序 我计划通过人们最喜欢的 QRCode 阅读器使用 QRCode 启动该应用程序 我的问题 如果我的应用程序尚未安装在他们的 iPhone iPad 上 会发生什么 他们会被引导
  • iOS 复合谓词

    我正在编写一个具有照片数据库的应用程序 每张照片都有多个与之关联的标签 并且该应用程序有一个带有大量切换的搜索页面 允许用户仅根据他们感兴趣的标签搜索照片 每个标签都存储了integerID 是因为它们对应于外部数据库的 ID 所以我尝试简
  • 将多个数组合并为一个数组

    如何将多个数组合并为一个二维数组 鉴于我有以下输入 var arr1 1 2 3 var arr2 a b c var arr3 aa bb cc 我需要这样的输出 1 a aa 2 b bb 1 c cc 我认为你想要的是将三个数组组合成
  • SDWebImage 显示缓存中图像的占位符

    在 iOS 5 1 项目 iPad 中使用 SDWebImage 3 我们展示相当大的图像 700x500 并且我们有很多图像 1000 我们预取图像并缓存到磁盘 然后允许用户浏览它们 效果很好 除了当您浏览图像时 您总是会看到占位符显示一
  • Python 队列 get()/task_done() 问题

    我的消费者端队列 m queue get queue task done
  • iOS 11 getUserMedia 不起作用?

    苹果公司发表声明称getUserMedia将在 iOS 11 上完全正常运行 安装 iOS 11 Beta 版本 5 后 我确实收到一条消息 表明我的网站请求访问我的相机和麦克风 但似乎是这样的 video src window URL c
  • AVAudioMixerNode pan 或 AVAudioUnitSamplerstereoPan 属性无法更改 AVAudioEngine 声音输出的左/右平衡

    我有以下代码 它播放单个 MIDI 音符 但我希望能够调整平衡 平移 以便它仅从左扬声器或右扬声器或某些组合中播放 我认为更改 sampler stereoPan 或 engine mainMixerNode pan 也许可以解决问题 但它
  • 使用 NSOutlineView 作为文件系统目录浏览器的 Swift 代码

    我已经在这段 Swift 代码上苦苦挣扎了一段时间 但没有发现问题 代码 下面应该提供文件目录作为 NSOutlineView 的数据源 GUI 非常简单 只是一个带有 NSOutlineView 和 OutlineViewControll
  • 您可以严格泛型类型或为一个参数指定多个类型吗?

    例如我想指定一个类型可能是Integer or String并将其用作特殊类型func我试过typealias但它不会解决这个问题 因为类型别名不能有or参数作为其唯一用途 因此请考虑下面的情况 typealias alis StringP
  • 如何正确使用 std::condition_variable?

    我很困惑conditions variables以及如何 安全 使用它们 在我的应用程序中 我有一个创建 gui 线程的类 但是当 gui 是由 gui 线程构造时 主线程需要等待 情况与下面的函数相同 主线程创建互斥体 锁和conditi

随机推荐

  • 使用 boost::spirit 读取空值

    我想将 CSV 读入结构中 struct data std string a std string b std string c 但是 我想读取空字符串以确保所有值都位于正确的位置 我将该结构调整为 boost fusion 因此以下工作有
  • 如何设置 Visual Studio Code 来编译 C++ 代码?

    微软的视觉工作室代码编辑器相当不错 但它没有默认支持构建 C 项目 我如何配置它来执行此操作 构建任务是特定于项目的 要创建新项目 请在 Visual Studio Code 中打开一个目录 Following the instructio
  • 使用 jQuery 解析远程内容的最佳实践是什么?

    在 jQuery ajax 调用检索整个 XHTML 文档之后 从结果字符串中选择特定元素的最佳方法是什么 也许有一个库或插件可以解决这个问题 jQuery 只能选择字符串中存在的 XHTML 元素 如果 W3C 规范中的 div 中通常允
  • 使用 Retrofit 将 json 结构转换为数组

    我遇到了 Retrofit 和 Trakt tv API 中丑陋的 json 对象的麻烦 season 1 episodes 1 true 2 true 3 false 4 false 5 false 6 false 7 false epi
  • 直接从 JSON 文件获取数据帧?

    首先 我要感谢所有为 Stackoverflow 和 R 做出贡献的人 我是那些不太擅长编程的 R 用户之一 但勇敢地尝试在工作中使用它 所以下面的问题可能是微不足道的 问题就在这里 我需要将 JSON 格式的文件导入到 R library
  • 滚动视图中的多个文本视图

    我有一项活动以文本形式显示步行方向 我有一组 TextView 其中 5 个包含 步骤 x 其中 x 是步骤号 另外 5 个 TextView 包含实际说明 问题是最后一个 TextView 离开屏幕 所以我想让这组 TextView 滚动
  • elasticsearch 2.0 父子孙子

    我的操作 父级 国家 地区 子级 分支机构 孙级 员工 PUT company 映射 分支 父 类型 国家 员工 父 类型 分支 我想添加一个孙子employee2 父级是分支 PUT company employee2 mapping e
  • 结构名称是否指向第一个元素?

    我发现了一些类似的问题 但没有一个有多大帮助 结构名称是否指向结构的第一个元素 类似于数组 struct example int foo int bar struct example e e foo 5 e bar 10 printf d
  • 隐藏提交按钮直到表单有效

    我对 Jquery 相当陌生 所以这可能是一个简单的问题 但是有没有办法隐藏表单上的提交按钮 直到验证所有字段 验证需要是 键入时 的解决方案 基本上我有 3 个字段 名字 姓氏和电子邮件 我希望提交按钮保持隐藏状态 直到填写了两个 名称
  • Ogre/Mogre:相机两点透视

    我正在显示一个场景 其中有一些立方体 相机采用的是透视法 一切都很好 但我希望垂直线是平行的 两点透视 http en wikipedia org wiki Perspective graphical 两点透视 从正面观察立方体时 我想要的
  • 如何将多列放入kivy RecycleView中?

    我想将 csv 表的数据放入 kivy recycleview 中 如果我为 kv 中的标签分配固定文本 我设法用一行插入多列 但我无法让它用字典列表中的数据填充标签 这是到目前为止我用来测试这个概念的代码 from kivy app im
  • 如何将存储过程的输出返回到sql server中的变量中

    我想在 SQL Server 中执行存储过程并将输出分配给变量 它返回单个值 这取决于您想要返回的信息的性质 如果它是单个整数值 则可以使用return陈述 create proc myproc as begin return 1 end
  • #include 检测到错误。请在 Visual Studio 代码中更新您的 includePath

    我正在尝试在 Visual Studio Code 中编译 C 文件如何使用 C C 扩展并添加包含路径到配置但我收到此错误 include errors detected Please update your includePath Sq
  • 使用javascript,如何在单击表格单元格时获取其背景颜色?

    我想要弹出一个警报 每当我单击它时 它都会显示表格单元格的背景 我似乎无法找到或弄清楚如何获取背景颜色 我的表格单元格如下所示 td 0 td 我的 selectCell 函数如下所示 function selectCell e alert
  • 如何在 C# 中将消息框显示为系统模式?

    如何在 C 中将消息框显示为系统模式 例如vbModal在 Visual Basic 6 中 使用 C MessageBoxIndirect 包装器进行高级 MessageBoxing
  • 将 Spring Security 与 SiteMinder 集成

    如何将 Spring Security 与 SiteMinder 集成以接收用户和角色 我有一个在内存中使用 Spring Security 的项目设置 我想使用它来接受具有用户和角色的 SiteMinder 标头 如果SiteMinder
  • 尝试使用 Scrapy 抓取 LinkedIn 时出现 999 响应

    我正在尝试使用 Scrapy 框架从 LinkedIn 中提取一些信息 我知道他们对尝试抓取其网站的人非常严格 因此我在 settings py 中尝试了不同的用户代理 我还指定了较高的下载延迟 但它似乎仍然立即阻止了我 USER AGEN
  • SKScene 无法释放内存,导致内存增长有限

    我已经为此苦苦挣扎了好几天 由于某种原因 我的 SKScenes 没有正确释放 这导致内存增长有限 因为每次我退出并进入场景时 内存都会跳跃 这意味着游戏进行 10 轮后应用程序崩溃 据我所知 经过多次检查后 我没有任何保留周期或对场景本身
  • C#:检测哪个应用程序具有焦点

    我希望创建一个 C 应用程序 根据当前具有焦点的应用程序来更改内容 因此 如果用户使用 Firefox 我的应用程序就会知道这一点 Chrome Visual Studio TweetDeck 等也是如此 这可能吗 如果可能的话 我将如何实
  • DispatchGroup 逻辑工作流程

    我正在尝试实施DispatchGroup如下 但如果第一个调用返回true 然后第二个返回false 那么总体结果将返回false 但是 如果第一个调用返回false 然后第二个返回true 那么总体结果将返回false这不是我所期望的 我