golang 并行网络请求_将并行网络请求与RxSwift结合

golang 并行网络请求

介绍 (Introduction)

Concurrency is a concept that every mobile developer should know. It is the notion of multiple things happening at the same time.

并发是每个移动开发人员都应了解的概念。 这是同时发生多件事的概念

The key is to divide our program into small tasks that can run in parallel, and the final result shouldn’t be affected by the order of the task completion, meaning if task A finishes before task B, the outcome should be the same as if task B finishes before task A.

关键是将程序划分为可以并行运行的小任务,并且最终结果不应受任务完成顺序的影响,这意味着,如果任务A在任务B之前完成,则结果应与任务B在任务A之前完成。

In the iOS ecosystem, there are several tools to achieve that:

在iOS生态系统中,有几种工具可以实现这一目标:

  • NSOperation

    NSO操作
  • NSThread

    NSThread
  • Grand Central Dispatcher

    大中央调度员
  • Reactive Programming frameworks like RxSwift, ReactiveSwift, Combine, etc

    响应式编程框架,例如RxSwift,ReactiveSwift,Combin等

When dealing with network requests, the recommended approach is to have an asynchronous task (the thread initiated the task won’t wait until the task is completed to continue executing other tasks) in a background thread (because the main thread should be free for UI updates only). This will guarantee a smooth, freeze-free user experience, that allows the user to continue using the app while the network request eventually finishes some time in the future.

处理网络请求时,推荐的方法是在后台线程中有一个异步任务 (启动该任务的线程将等到该任务完成后再继续执行其他任务)(因为主线程应可用于UI)仅更新)。 这将确保流畅,无冻结的用户体验,使用户可以继续使用应用程序,同时网络请求最终会在将来的某个时间结束。

Parallel execution improves the overall speed of the app, if task A takes 2 seconds and task B takes 3 seconds, the 2 tasks running in parallel would take 3 seconds, whereas running in serial (one after the other) would take 5 seconds.

并行执行可提高应用程序的整体速度,如果任务A花费2秒,任务B花费3秒,则并行运行的2个任务将花费3秒,而串行运行(一个接一个)将花费5秒。

实际用例 (Real-world use case)

In the classifieds company I worked, there was a screen on the app to display the search results using a UITableView, and the Business wanted to display Featured (premium/paid) results on top of the regular/free results, a practice widely used in the e-commerce and classified world.

在我工作的分类公司中,应用程序上有一个屏幕,用于使用UITableView显示搜索结果,而企业希望在常规/免费结果之上显示精选(付费/付费)结果,这种做法在电子商务和机密世界。

The backend had 2 different endpoints to be consumed, one for regular results, one for premium results, and both require the same parameters. The discussion of whether or not the endpoints should be merged into one is for another post.

后端有2个不同的端点需要使用,一个端点用于常规结果,一个端点用于高级结果,并且都需要相同的参数。 讨论是否应将端点合并为另一篇文章。

In order to maximize the premium results exposure, and provide a better user experience, it was decided to execute both network requests at the same time, and wait until both finish before updating the UI. Meaning if request A takes 500ms and request B takes 3 seconds, the user will see a loading screen for 3 seconds.

为了最大限度地提高优质结果的曝光率并提供更好的用户体验,决定同时执行两个网络请求,并等到两个请求都完成后再更新UI。 这意味着如果请求A花费500毫秒而请求B花费3秒,则用户将看到3秒钟的加载屏幕。

实作 (Implementation)

Let’s review the implementation using RxSwift, a popular open-source reactive programming framework, widely used across our app.

让我们使用RxSwift(一种流行的开源React式编程框架)进行回顾,该框架在我们的应用程序中广泛使用。

We start by creating a method getResults that will receive a dictionary with parameters, and return a Single of Array of Result. The actual implementation is not relevant here, but is basically a network request using URLSession, Alamofire, or any other library, map the response to an array of Result, where Result is just a model representing a single Ad that eventually will be displayed as a row in a list view.

我们从创建方法getResults开始,该方法将接收带有参数的字典,并返回Result of Array的Single 。 实际的实施方式在这里不相关,但基本上是使用URLSession,Alamofire或任何其他库的网络请求,会将响应映射到Result数组,其中Result只是代表单个广告的模型,最终将显示为列表视图中的行。

A Single is an Observable that emits either one value or an error. Alternatively, the method could return Observable<Result>, that would be emitting as many values as elements on the network response. But eventually the sequence will be converted to an Array, therefore I think is cleaner to just return Single<[Result]> here.

Single是一个Observable,它发出一个值或一个错误。 或者,该方法可以返回Observable<Result> ,该值将发出与网络响应上的元素一样多的值。 但是最终该序列将被转换为数组,因此我认为在此处返回Single<[Result]>更为干净。

Then, we create and hold reference to the sequence like so:

然后,我们创建并保持对序列的引用,如下所示:

This won’t execute the sequences (nor the underlying network requests) yet.

这将不会执行序列(也不会执行底层网络请求)。

The next step is to create a final sequence combining both network responses.We will use the Zip operator, that combines the emissions of multiple sequences via a given function, and returns a single item for each combination.

下一步是创建结合了两个网络响应的最终序列,我们将使用Zip运算符,该运算符通过给定的函数组合多个序列的发射,并为每个组合返回一个项目。

In our example, promotedAdsSequence will emit one value (Array of Result) and regularAdsSequence will also emit one value, therefore the Zip operator will return a sequence that only emits one value.

在我们的示例中, promotedAdsSequence将发出一个值(结果数组), regularAdsSequence也将发出一个值,因此Zip运算符将返回仅发出一个值的序列。

Since both sequences are of type Single, the Zip operator has to be invoked on the same type.

由于两个序列的类型均为Single ,因此必须在同一类型上调用Zip运算符。

This is still not firing the requests, in order to do so, we need an Observer to subscribe to finalSequence:

这仍然没有触发请求,为此,我们需要一个Observer来订阅finalSequence

This last snipped is the one triggering the parallel network requests, and the onSuccess block will be executed when both finish successfully. If one fails, the whole operation fails.

最后一个片段是触发并行网络请求的片段,当两个成功完成时,将执行onSuccess块。 如果失败,则整个操作将失败。

捕捉错误 (Catching errors)

But even though the tasks are in parallel and the operation is atomic, the call to get regular ads is the main one, and if the promoted call fails, we can at least show the regular ads instead of an error message.

但是,即使任务是并行的并且操作是原子的,获取常规广告的调用仍是主要的,如果升级后的调用失败,我们至少可以显示常规广告而不是错误消息。

The solution to this is to catch the error on the promoted sequence and return just an empty error:

解决方案是捕获升级序列上的错误并仅返回一个空错误:

结论 (Conclusion)

It is mandatory for a mobile developer to have a good understanding of threads, sync vs async operations, serial vs concurrent queues, in order to create a smooth user experience, and efficiently use the resources issued by the OS to us.

移动开发人员必须对线程,同步与异步操作,串行与并发队列有充分的了解,以便创建流畅的用户体验,并有效地使用操作系统向我们提供的资源。

Reactive programming and frameworks like RxSwift provides the interface to easily manage async operations in a declarative way, manipulating and combining the data through various operators, and keeping in mind the memory management to avoid potential leaks.

诸如RxSwift之类的React式编程和框架提供了以声明方式轻松管理异步操作,通过各种运算符操纵和组合数据以及记住内存管理以避免潜在泄漏的接口。

其他职位 (Other posts)

翻译自: https://medium.com/flawless-app-stories/combining-parallel-network-requests-with-rxswift-68771111c039

golang 并行网络请求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值