duan1933 2018-11-08 12:25
浏览 268

如何在golang中顺序处理并发请求? [重复]

This question already has an answer here:

I'm new to Golang and I found go channels very interesting. My background is from JavaScript and I want to handle concurrent request sequentially in Go, sort of like Promise.all() in JavaScript. All I want is to make some requests which run concurrently and handle the returned data the order in which I have called them.

The equivalent JavaScript code will be like as follows:

async function main() {
  // Assuming all db calls will return a promise
  const firstUserPromise = firstDbCall().then((res) => res);
  const secondUserPromise = secondDbCall().then((res) => res);
  const thridUserPromise = thridDbCall().then((res) => res);

  const [
    firstUserData,
    secondUserData,
    thirdUserData
  ] = await Promise.all([firstUserPromise, secondUserPromise, thirdUserPromise]);
}

If you are not familiar with JavaScript, in the above code I'm making three database calls which are happening concurrently (from line 3 to 5). And then I'm waiting for them to give to some responses (from line 7 to 10). What nice about this code is when all three database calls are finished, I'll get the results in the order of which I'm waiting for them. firstUserData will get response from firstUserPromise, secondUserData will get from secondUserPromise and so on.

Below is a hypothetical code which I'm wanting to be equivalent of the above JavaScript code:

package main

import "fmt"

func main() {
  set = make(chan, string)
  get = make(chan, string)

  // First DB call
  go firstDbCall()
  // Second DB call
  go secondDbCall()
  // Third DB call
  go thirdDbCall()

  // How to make sending data to channels predictable
  // First data to `set` channel will send data to firstDbCall
  // Second one will `set` to secondDbCall and so on.
  set <- "userId 1"
  set <- "userId 2"
  set <- "userId 3"

  // Similarly, How to make receiving data from channels predictable
  // firstUserData will data of "userId 1", secondUserData will have
  // data of "userId 2" and so on.
  firstUserData := <-get
  secondUserData := <-get
  thirdUserData := <-get
}

Because of getting data from channels are unpredictable how can I make them predictable like the JavaScript code?

</div>
  • 写回答

2条回答 默认 最新

  • dongwei7913 2018-11-08 13:37
    关注

    Go channels are really just thread safe queues. In this case, it doesn't look like a queue (and therefore a channel) fit your use case. I would recommend looking at sync.WaitGroup.

    package main
    
    import "sync"
    
    func main() {
        var (
            firstUserData, secondUserData, thirdUserData string
            wg                                           sync.WaitGroup
        )
        wg.Add(3)
    
        // First DB call
        go func() {
            defer wg.Done()
            firstUserData = firstDbCall()
        }()
    
        // Second DB call
        go func() {
            defer wg.Done()
            secondUserData = secondDbCall()
        }()
    
        // Third DB call
        go func() {
            defer wg.Done()
            thirdUserData = thirdDbCall()
        }()
    
        wg.Wait()
    
        println(firstUserData, secondUserData, thirdUserData)
    }
    
    func firstDbCall() string {
        return "UserId1"
    }
    
    func secondDbCall() string {
        return "UserId2"
    }
    
    func thirdDbCall() string {
        return "UserId3"
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型