当前位置: 首页 > news >正文

Go 语言并发实战:利用协程处理多个接口进行数据融合

高效地处理多个数据源并将其整合为有意义的结果是开发中一项重要的任务。Go 语言,以其强大的并发特性,为我们提供了优雅而高效的解决方案。那么我们探讨一下如何利用 Go 语言的协程,同时调用多个接口获取数据,并将这些数据无缝地合并为一个完整的数据集。

先假定一个场景:现有一需求,需要请求n个接口(暂定为3个)获取接口数据,然后对数据进行二次处理并返回。

按照过往的经验,我们会依次请求接口拿到数据暂存,最后对数据进行包装处理,这种自上而下的处理方式其实并无不妥,现在想要提高下效率,利用牺牲cpu资源来换取查询性能。

  1. 先模拟创建几个接口,分别返回(k1,v1)、(k2,v2)、(k3,v4):

    // 模拟接口A
    func getDataFromA() map[string]interface{} {return map[string]interface{}{"key1": "value1",}
    }// 模拟接口B
    func getDataFromB() map[string]interface{} {return map[string]interface{}{"key2": "value2",}
    }// 模拟接口C
    func getDataFromC() map[string]interface{} {return map[string]interface{}{"key3": "value3",}
    }
    
  2. 开启协程分别请求上述接口:
    首先得思考一个问题,协程执行不保证顺序,请求到的数据应该怎么保存?怎么判断全部协程都执行完毕?怎么拿到全部的数据?

    • 上述接口定义中返回的数据均是 map,那么我完全可以用map来保存数据,所以我定义方法就可以这么定义:

      func getAllData() map[string]interface{} {return nil    // 暂时先不做处理
      }
      
    • 为了防止主协程先于其他执行结束,需要引入 sync.WaitGroup 包控制;所有协程返回的数据,可以用通道来暂存,make 一个容量为 3 的 Channel

      func getAllData() map[string]interface{} {var wg sync.WaitGroupresultChan := make(chan map[string]interface{}, 3)return nil    // 暂时先不做处理
      }
      
    • 接下来就可以开启协程去调用:

      func getAllData() map[string]interface{} {var wg sync.WaitGroupresultChan := make(chan map[string]interface{}, 3)wg.Add(3)go func() {defer wg.Done()resultChan <- getDataFromA()}()go func() {defer wg.Done()resultChan <- getDataFromB()}()go func() {defer wg.Done()resultChan <- getDataFromC()}()wg.Wait()close(resultChan)return nil // 暂时先不做处理
      }
      
    • 最后可以对数据做个简单处理,封装成一个大map返回,实际业务当然按需处理:

      newMap := make(map[string]interface{})for res := range resultChan {for k, v := range res {newMap [k] = v}
      }return newMap
      
  3. 执行验证返回结果:

    func main() {newMap := getAllData()fmt.Println(newMap)
    }
    
    [Running] go run "main.go"
    map[key1:value1 key2:value2 key3:value3]
    

http://www.lryc.cn/news/508150.html

相关文章:

  • Redis Hash Tag 知识详解
  • 在 Ubuntu 上安装 Muduo 网络库的详细指南
  • Golang Gin Redis+Mysql 同步查询更新删除操作(我的小GO笔记)
  • nodejs搭配express网站开发后端接口设计需要注意事项
  • mysql 基于chunk机制是如何支持运行期间,动态调整buffer pool大小的
  • 智能客户服务:AI与大数据的革新力量
  • Python日常使用的自动化脚本
  • 代理模式(JDK,CGLIB动态代理,AOP切面编程)
  • 【Leetcode 热题 100】236. 二叉树的最近公共祖先
  • Go框架比较:goframe、beego、iris和gin
  • Kafka Streams 在监控场景的应用与实践
  • 数据结构 -- 二叉树
  • redis数据转移
  • Ubuntu Netlink 套接字使用介绍
  • spring boot密码加密方式
  • springboot根据租户id动态指定数据源
  • 使用C语言编写UDP循环接收并打印消息的程序
  • 【AI】✈️问答页面搭建-内网穿透公网可访问!
  • 计算机毕业设计原创定制(免费送源码):NodeJS+MVVM+MySQL 樱花在线视频网站
  • ECharts热力图-笛卡尔坐标系上的热力图,附视频讲解与代码下载
  • 【Lua热更新】下篇
  • Facebook 与数字社交的未来走向
  • 微信小程序实现二维码海报保存分享功能
  • Android 搭建AIDL Client和Server端,双向通信
  • 深度学习从入门到精通——图像分割实战DeeplabV3
  • STM32-笔记5-按键点灯(中断方法)
  • C++ 只出现一次的数字 - 力扣(LeetCode)
  • C++设计模式:享元模式 (附文字处理系统中的字符对象案例)
  • android EditText密码自动填充适配
  • LeetCode 刷题笔记