从另一个队列中轮询一个简单队列,并从第二个队列中填充第一个队列

时间:2017-08-31 19:54:59

标签: go queue

换句话说,事件驱动队列的流程:

  • 民意调查事件队列
  • 如果找到事件,处理事件,然后是下一个轮询周期
  • 如果未找到任何事件,则轮询数据队列
  • 如果找到数据,则推送到事件队列,启动下一个循环轮询事件队列
  • 如果没有找到数据,退出流程

以下是代码:

package main

import "fmt"

type Queue struct {
    stream []string
}

// Next returns first element from stream.
// Returns false if no element is in the stream.
func (q *Queue) Next() (s string, ok bool) {
    if len(q.stream) == 0 {
        return s, false
    }
    s = q.stream[0]
    q.stream = q.stream[1:]
    return s, true
}

func main() {
    // define queues
    events := []string{"event"}
    q1 := &Queue{stream: events}
    data := []string{"data1", "data2", "data3"}
    q2 := &Queue{stream: data}

    // poll first queue
    for e, ok := q1.Next(); ok; e, ok = q1.Next() {
        // nothing in q1
        if !ok {
            fmt.Println("Nothing found in q1")

            // poll second queue
            d, ok := q2.Next()
            if !ok {
                return
            }

            // found d in q2 and append to q1
            fmt.Printf("found in q2 %v\n", d)
            q1.stream = append(q1.stream, d)
            return
        }

        // do some stuff to e ...
        fmt.Printf("found in q1 %v %v\n", e, ok)
    }
}

在游乐场https://play.golang.org/p/bgJzq2hCfl尝试。

我得到的只是第一个队列中的元素。

found in q1 event true

代码从不轮询第二个队列并将其元素附加到第一个队列。我错了什么?

如果我尝试

// poll first queue
for e, ok := q1.Next() {
    // ...
}

编译器抛出

tmp/sandbox299553905/main.go:28:25: syntax error: e, ok := q1.Next() used as value

任何提示都表示赞赏。

更新:以下是循环的解决方案。

// poll first queue
for e, ok := q1.Next(); true; e, ok = q1.Next() {
    // nothing in q1
    if !ok {
        fmt.Println("Nothing found in q1")

        // poll second queue
        for d, ok := q2.Next(); true; d, ok = q2.Next() {
            if !ok {
                fmt.Println("Nothing found in q2. exit")
                return
            }

            // found d in q2 and append to q1
            fmt.Printf("found in q2: %v. append to q1\n", d)
            q1.stream = append(q1.stream, d)
            break
        }
        continue
    }

    // do some stuff to e ...
    fmt.Printf("found in q1: %v. do stuff\n", e)
}

您可以在游乐场https://play.golang.org/p/qo0zoBPROe进行测试。

2 个答案:

答案 0 :(得分:2)

当它找不到任何内容时退出循环。只需将for循环更改为以下内容,但请注意,这会使循环无限,因此您必须break out或return才能退出。

for e, ok := q1.Next(); ok || !ok ; e, ok = q1.Next() {

答案 1 :(得分:2)

第一次迭代后,“增量”发生,此时ok设置为false。下一步比较ok == true(循环终止条件),这不是这种情况,因此退出。

现在,如果我理解你尝试做什么,我会将循环修改为:

// poll first queue
for e, ok := q1.Next(); true; e, ok = q1.Next() {
    // nothing in q1
    if !ok {
        fmt.Println("Nothing found in q1")

        // poll second queue
        d, do := q2.Next()
        if !do {
            break
        }

        // found d in q2 and append to q1
        fmt.Printf("found in q2 %v\n", d)
        q1.stream = append(q1.stream, d)
    } else {

        // do some stuff to e ...
        fmt.Printf("found in q1 '%v' ok=%v\n", e, ok)
    }
}