MST

星途 面试题库

面试题:Go接口异步编程中如何优雅地处理多个异步任务的结果

假设你有多个使用Go接口异步执行的任务,每个任务返回不同类型的结果,例如一个任务返回用户信息,一个任务返回用户的权限列表。请描述如何使用Go的特性(如goroutine、channel等)来优雅地收集并处理这些结果,同时要考虑错误处理。
35.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 定义任务和结果类型
    • 首先定义每个任务返回的结果类型。例如:
    type UserInfo struct {
        Name string
        Age  int
    }
    type UserPermissions []string
    
  2. 定义任务函数
    • 为每个任务定义一个函数,这些函数返回相应的结果和可能的错误。例如:
    func getUserInfo() (UserInfo, error) {
        // 模拟获取用户信息,这里可能是从数据库查询等操作
        return UserInfo{Name: "John", Age: 30}, nil
    }
    func getUserPermissions() (UserPermissions, error) {
        // 模拟获取用户权限列表,可能是从权限系统查询
        return UserPermissions{"read", "write"}, nil
    }
    
  3. 使用goroutine和channel收集结果
    • 创建用于接收结果和错误的channel。
    infoCh := make(chan UserInfo, 1)
    permCh := make(chan UserPermissions, 1)
    errCh := make(chan error, 2)
    
    • 使用goroutine异步执行任务,并将结果发送到相应的channel。
    go func() {
        info, err := getUserInfo()
        if err!= nil {
            errCh <- err
        } else {
            infoCh <- info
        }
        close(infoCh)
    }()
    go func() {
        perm, err := getUserPermissions()
        if err!= nil {
            errCh <- err
        } else {
            permCh <- perm
        }
        close(permCh)
    }()
    
  4. 处理结果和错误
    • 使用select语句等待所有任务完成,并处理结果和错误。
    var userInfo UserInfo
    var userPermissions UserPermissions
    var errors []error
    for i := 0; i < 2; i++ {
        select {
        case info := <-infoCh:
            userInfo = info
        case perm := <-permCh:
            userPermissions = perm
        case err := <-errCh:
            errors = append(errors, err)
        }
    }
    close(errCh)
    if len(errors) > 0 {
        // 处理错误,例如记录日志或返回错误给调用者
        for _, err := range errors {
            log.Println("Error:", err)
        }
        return
    }
    // 处理收集到的结果
    fmt.Printf("User Info: %+v\n", userInfo)
    fmt.Printf("User Permissions: %+v\n", userPermissions)
    

总结来说,通过goroutine实现任务的异步执行,通过channel来传递结果和错误,再利用select语句优雅地收集并处理这些结果和错误。这样可以充分利用Go语言的并发特性,高效地处理多个异步任务。