Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >方法在从Combine Future Publisher接收数据之前结束

方法在从Combine Future Publisher接收数据之前结束
EN

Stack Overflow用户
提问于 2020-03-09 13:31:54
回答 1查看 259关注 0票数 0

我有这样的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Cocoa
import Combine

func prepareURLRequest(for url: URL) -> URLRequest {
    let request = URLRequest(url: url)
    var token = "token"

    print("start value: \(token)")

    let subscription = Token()
    subscription.getToken()
        .sink(receiveCompletion: { _ in
        print("subscription completed")
    }, receiveValue: { value in
        token = value
        print("value received: \(token)")
    })

    print("new value: \(token)")

    // attach received token to request
    return request
}


class Token {
    let token = PassthroughSubject<String,Never>()

    func verify() -> Bool {
        // TODO: Token verification logic
        Bool.random()
    }

    func getToken() -> AnyPublisher<String,Never> {
        return Future<String, Never> { promise in
            if self.verify() {
                let url = URLRequest(url: URL(string: "http://avatars.io/twitter/twostraws")!)
                URLSession.shared.dataTask(with: url) { data, response, error in
                    print("Data Task started")
                    if let error = error {
                        print("error \(error)")

                    }
                    guard let data = data else {
                        preconditionFailure("data error")
                    }
                    guard let response = response as? HTTPURLResponse else {
                        preconditionFailure("response error")
                    }

                    print("data task received response with code: \(response.statusCode)")
                    promise(.success("\(response.statusCode)"))
                }.resume()
            } else {
                print("keychain path")
                sleep(2)
                promise(.success("kwychain path success"))
            }
        }.eraseToAnyPublisher()
    }
}

let url = URL(string: "http://avatars.io/twitter/twostraws")!
let request = prepareURLRequest(for: url)

代码应将接收的令牌附加到准备好的请求对象。现在,唯一的verify -> false path以所需的顺序返回数据。当我尝试在prepareURLRequest结束其生命周期后,verify -> true路径数据被接收。

如何修复这一问题,使两个路径都有正确的顺序(并且在prepareURLRequest方法结束之前更新令牌?

EN

回答 1

Stack Overflow用户

发布于 2020-03-13 01:03:47

你遇到的问题是,你没有用一个延迟来包装未来。您编写的代码期望在请求请求之前不会进行API调用,但这并不完全是Future的工作方式。

一旦创建了Future,它就会调用它的底层异步API调用来呈现-而你使用的是上面的PassthroughSubject,这意味着当你有一个订阅者请求数据时,它已经被调用了。解决此问题的最好方法是将Future包装在Deferred发布服务器中,该发布服务器等待创建它,直到订阅请求数据为止。

这里有an example of wrapping Future with Deferred in the Future reference page of Using Combine,以及更多关于未来如何工作以及其他运营商如何使用它的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60601645

复制
相关文章
Combine-Publisher
概念 Combine 中包括Publisher在内的一系列角色都使用协议来进行定义,这是 Swift 面向协议编程思想的具体体现。 Publisher 随着时间推移向一个或多个Subscriber发布数据。 Publisher 最主要的工作其实有两个 被 Subscriber 订阅 发布数据和数据 Publisher定义 public protocol Publisher { /// 发送的数据的类型 associatedtype Output /// Publisher可能产生
YungFan
2020/04/09
7770
Combine-Future
前面我们用过Just,其数据的发布和订阅是同步行为。如果希望数据的发布和订阅是异步的,可以使用Future。Future可以创建一个接收未来数据与事件的 Publisher。Future定义如下:
YungFan
2020/05/20
8110
Combine-Foundation中的Publisher
为了方便使用,Foundation 为 iOS 开发中的几个常见操作提供了直接获取 Publisher 的方式。
YungFan
2020/03/24
1.2K0
Combine-Subscriber
Publisher 根据 Subscriber 的请求提供数据。如果没有任何订阅请求,Publisher 不会提供任何数据。所以可以这样说,Subscriber负责向 Publisher 请求数据并接收数据(或失败)。
YungFan
2020/04/16
9960
Combine-Subscriber
聊聊 Combine 和 async/await 之间的合作
在 Xcode 13.2 中,苹果完成了 async/await 的向前部署(Back-deploying)工作,将最低的系统要求降低到了 iOS 13(macOS Catalina),这一举动鼓舞了越来越多的人开始尝试使用 async/await 进行开发。当大家在接触了异步序列(AsyncSequence)后,会发现它同 Combine 的表现有些接近,尤其结合近两年 Combine 框架几乎没有什么变化,不少人都提出了疑问:苹果是否打算使用 AsyncSequence 和 AsyncStream 替代 Combine。
东坡肘子
2022/07/28
8750
干货 | 深入浅出Apple响应式框架Combine
Combine.framework 是Apple在2019 WWDC 上基于Swift推出的函数响应框架(Functional Reactive Programming),支持Apple全平台的操作系统(iOS13+,macOS 10.15+等)。函数式响应框架无论在哪个平台早已流行泛滥,开源的Rx更是实现了各种语言的响应式编程框架。Apple在这个时候推出响应式框架,无疑是对自己护城河的进一步巩固。事实上SwiftUI的数据驱动就是依赖Combine。
携程技术
2020/11/04
4.2K0
干货 | 深入浅出Apple响应式框架Combine
Akka(17): Stream:数据流基础组件-Source,Flow,Sink简介
    在大数据程序流行的今天,许多程序都面临着共同的难题:程序输入数据趋于无限大,抵达时间又不确定。一般的解决方法是采用回调函数(callback-function)来实现的,但这样的解决方案很容易
用户1150956
2018/01/05
1.7K0
聊聊reactive streams publisher的doOn方法
本文主要研究一下reactive streams Publisher的doOn方法
code4it
2018/09/17
1.2K0
activity结束之后刷新之前的activity的内容
点击添加按钮之后-----弹出一个新的activity--------在新的activity将数据输入保存之后,关闭当前的activity回到之前的activity刷新内容 实现:使用onActivityResult 启动页: btnButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent i
欢醉
2018/01/22
9030
Combine-Subject
Subject是一种特殊的 Publisher,最大的特点是可以手动发送数据。定义如下:
YungFan
2020/05/09
7310
Combine之Backpressure
我们在使用订阅者的时候,都是用Sink或者Assign,但是大家有没有想过一个问题,这两种订阅者在第一次连接到发布者的时候,会发送一个无限大(unlimited)的需求(Demand)。
CC老师
2022/03/15
6090
Combine之Backpressure
Combine-实践
Combine 既可以在 SwiftUI 中使用,也可以在 UIKit 中使用。下面分别实践一下。
YungFan
2020/05/18
1.3K0
Combine-Scheduler
如果说 Publisher 决定了发布什么样的 (what) 数据的话,Scheduler(调度器) 所要解决的就是两个问题:在什么地方 (where),以及在什么时候 (when) 来发布数据和接收数据。我们都知道,在 iOS 开发中如果需要更新 UI,需要保证相关操作发生在主线程。在 Combine 中如果数据流前面的 Publisher 是在后台线程进行操作,那么在订阅时,当状态的变化会更新 UI 时,需要将数据流中接收数据的线程切换到主线程。
YungFan
2020/05/18
5720
Combine-Operator
默认情况下,订阅某个 Publisher,Subscriber 中的Input和Failure要与 Publisher Output和Failure类型相同,但实际开发中往往是不同的,此时就需要借助Operator进行转换。Operator 遵守 Publisher 协议,负责从数据流上游的 Publisher 订阅值,经过转换生成新的 Publisher 发送给下游的 Subscriber。
YungFan
2020/04/30
5130
Combine-AnyPublisher
Publisher 中的 Output 和 Failure 两个关联类型如果进行多次嵌套会让类型变得非常复杂,难以阅读,而实际开发中往往需要经过多次的操作才能得到合适的 Publisher。 对于 Subscriber 来说,只需要关心 Publisher 的 Output 和 Failure 两个类型就能顺利订阅,它并不需要具体知道这个 Publisher 是如何得到、如何嵌套的。 为了对复杂类型的 Publisher 进行类型抹消,Combine 提供了eraseToAnyPublisher()方法将复
YungFan
2020/05/09
1.9K0
了解 Swift 调度器
iOS 应用开发中最常见的错误之一是线程错误,当开发者试图从一个闭包中更新用户界面时,会出现这种错误。为了解决这个问题,我们可以使用 DispatchQueue.main 和 threads。
Swift社区
2021/11/26
2.6K0
Combine 基本概念
订阅者调用request(_:_)来告知愿意接受更多的值,从一个最大的值,到无限制。
小刀c
2022/09/21
2960
你还在从零搭建项目 ?
在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为“第0个迭代”要做的事情。但是,当项目运行了一段时间之后再来反观,我总会发现一些不足的地方,要么测试分类没有分好,要么基本的编码架子没有考虑周全。
好好学java
2019/12/05
4750
你还在从零搭建项目 ?
手把手教你入门AIoT(4)
在第一课中,我们介绍了 MQTT 基于订阅与发布的消息模型,MQTT 协议的订阅与发布是基于主题的(Topic),一个典型的 MQTT 消息发送与接收的流程如下:
刘盼
2019/03/15
5990
点击加载更多

相似问题

Combine Future Publisher未被释放

114

Combine Future publisher正在泄露

114

为SwiftUI Combine publisher生成错误(失败)的方法

120

带有Combine框架的Publisher mapError

222

在从服务器接收数据之前,如何防止方法触发?

33
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文