第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何在 Go API 中并發(fā)運(yùn)行函數(shù),而不是順序運(yùn)行函數(shù)?

如何在 Go API 中并發(fā)運(yùn)行函數(shù),而不是順序運(yùn)行函數(shù)?

Go
料青山看我應(yīng)如是 2022-08-01 11:07:51
在API中,如果我們需要查詢多個(gè)表,我們?nèi)绾瓮瑫r(shí)實(shí)現(xiàn)它,而不是遵循順序方式,即func sampleAPI(w http.ResponseWriter, r *http.Request) {    a, err := getFromATable();  //1    if err != nil {       w.WriteHeader(http.StatusInternalServerError)       return    }    b, err := getFromBTable();  //2    if err != nil {       w.WriteHeader(http.StatusInternalServerError)       return    }    c, err := getFromCTable();  //3    if err != nil {       w.WriteHeader(http.StatusInternalServerError)       return    }    .    .    .}我想同時(shí)調(diào)用上述函數(shù)1,2,3。我怎樣才能做到這一點(diǎn)
查看完整描述

3 回答

?
手掌心

TA貢獻(xiàn)1942條經(jīng)驗(yàn) 獲得超3個(gè)贊

使用錯(cuò)誤通道進(jìn)行同步

func sampleAPI(w http.ResponseWriter, r *http.Request) {

    chErr := make(chan error)


    var a correctType

    go func() {

        var err error

        a, err = getFromATable()

        chErr <- err

    }()


    var b correctType

    go func() {

        var err error

        b, err = getFromBTable()

        chErr <- err

    }()


    var c correctType

    go func() {

        var err error

        c, err = getFromCTable()

        chErr <- err

    }()


    var err error

    for i := 0; i < 3; i++ {

        if r := <-chErr; r != nil {

            err = r

        }

    }

    if err != nil {

        w.WriteHeader(http.StatusInternalServerError)

        // etc.

        return

    }


    // continue to do stuff with a, b, c

}

一些注意事項(xiàng):

  • 每個(gè) go 函數(shù)都必須向 添加一個(gè)值。確保它!如果沒有錯(cuò)誤,則寫入(如果沒有錯(cuò)誤,此示例將寫入)。chErrnilchErr

  • for 循環(huán)必須迭代與啟動(dòng) go 函數(shù)相同的數(shù)量。

  • for 循環(huán)確保所有函數(shù)都已完成(有或沒有錯(cuò)誤),然后再繼續(xù)。

  • 使用錯(cuò)誤進(jìn)行同步很方便,因?yàn)樗鼘?duì)于所有函數(shù)都是相同的類型。返回類型可能不同。如果我們需要在錯(cuò)誤時(shí)取消,我們無論如何都需要將錯(cuò)誤從goroutines中取回。

使用errgroup

正如 @Зелёный 在注釋中所建議的那樣,這里有一個(gè)使用(仍然)實(shí)驗(yàn)包錯(cuò)誤組的示例

func sampleAPI(w http.ResponseWriter, r *http.Request) {

    g, ctx := errgroup.WithContext(context.TODO())


    var a correctType

    g.Go(func() (err error) {

        a, err = getFromATable(ctx)

        return err

    })


    var b correctType

    g.Go(func() (err error) {

        b, err = getFromBTable(ctx)

        return err

    })


    var c correctType

    g.Go(func() (err error) {

        c, err = getFromCTable(ctx)

        return err

    })


    if err := g.Wait(); err != nil {

        w.WriteHeader(http.StatusInternalServerError)

        // etc.

        return

    }


    // continue to do stuff with a, b, c

}

一些注意事項(xiàng):

  • 這個(gè)檢查所有錯(cuò)誤,并為您返回第一個(gè)錯(cuò)誤。

  • 如果一個(gè)錯(cuò)誤,它還會(huì)取消剩余的調(diào)用(因此ctx)

  • 它使用sync.WaitGroup

  • 缺點(diǎn):它是一個(gè)額外的依賴項(xiàng),因?yàn)樗皇菢?biāo)準(zhǔn)庫(kù)的一部分(尚未)。

使用WaitGroup

還可以使用 a 來等待所有函數(shù)都返回其結(jié)果。sync.WaitGroup

func sampleAPI(w http.ResponseWriter, r *http.Request) {

    var wg sync.WaitGroup

    wg.Add(3)


    var a correctType

    var errA error

    go func() {

        defer wg.Done()

        a, errA = getFromATable()

    }()


    var b correctType

    var errB error

    go func() {

        defer wg.Done()

        b, errB = getFromBTable()

    }()


    var c correctType

    var errC error

    go func() {

        defer wg.Done()

        c, errC = getFromCTable()

    }()


    wg.Wait()

    

    if errA != nil {

        w.WriteHeader(http.StatusInternalServerError)

        // etc.

        return

    }

    if errB != nil {

        w.WriteHeader(http.StatusInternalServerError)

        // etc.

        return

    }

    if errC != nil {

        w.WriteHeader(http.StatusInternalServerError)

        // etc.

        return

    }


    // continue to do stuff with a, b, c

}

一些注意事項(xiàng):

  • 這里需要 3 個(gè)錯(cuò)誤變量。

  • 您需要在 之后檢查所有3個(gè)錯(cuò)誤變量,使其有點(diǎn)冗長(zhǎng)。wg.Wait



查看完整回答
反對(duì) 回復(fù) 2022-08-01
?
慕碼人8056858

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊

您還可以使用等待組來等待所有 api 調(diào)用完成,然后再繼續(xù)操作:


func sampleAPI(w http.ResponseWriter, r *http.Request) {

    var res1, res2, res3 myCustomType

    var err1, err2, err2 error


    var wg sync.WaitGroup

        wg.Add(3)


    go func() {

        defer wg.Done()

        res1, err1 = getFromATable();  //1

    }()


    go func() {

        defer wg.Done()

        res2, err2 = getFromBTable();  //2

    }()


    go func() {

        defer wg.Done()

        res3, err3 = getFromXTable();  //3

    }()


    wg.Wait()

}

進(jìn)一步參考也 https://gobyexample.com/waitgroups 和 https://tutorialedge.net/golang/go-waitgroup-tutorial/


查看完整回答
反對(duì) 回復(fù) 2022-08-01
?
慕妹3146593

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超9個(gè)贊

如果 a、b 和 c 是不同的類型,則可以嘗試以下方法。interface{}類型只是為了展示如何編碼,你可以根據(jù)自己的要求修改通道類型。


    aCh := make(chan interface{})

    bCh := make(chan interface{})

    cCh := make(chan interface{})

    defer close(aCh)

    defer close(bCh)

    defer close(cCh)

    

    go func() {

      a, _ := GetFromATable()

      aCh <- a

    }()

    go func() {

      b, _ := GetFromBTable()

      bCh <- b

    }()

    go func() {

      c, _ := GetFromCTable()

      cCh <- c

    }()


    fmt.Println(<- aCh, <- bCh, <- cCh)

如果所有三個(gè)輸出都處于同一類型,則只需使用單個(gè)通道或使用帶有 select 語句的 forever for 循環(huán)來處理流式處理要求。


查看完整回答
反對(duì) 回復(fù) 2022-08-01
  • 3 回答
  • 0 關(guān)注
  • 143 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)