【问题标题】:How to exit loop in an async call?如何在异步调用中退出循环?
【发布时间】:2018-10-28 06:27:14
【问题描述】:

我的代码的简化版是这样的:

var joined = false

for room in rooms {
    checkRoom() { // async func
        if room.player.count == 1 { 
            join(room)
            joined = true
            // break doesnt work here
        }
    }

    if joined {
        break;
    }
}

我需要退出这个循环,因为它在加入一个房间后仍在检查其他房间。当加入成为真的时,我想停止检查其他房间。但是当然它只在异步调用中变为真的,所以我的方法不起作用。

join 为真时如何退出这个循环?

【问题讨论】:

  • 首先,您是要并行还是串行检查房间。如果您可以连续进行,那么它非常简单;不要使用for 循环,只需检查闭包中else 语句中的下一个房间
  • @Paulw11 哦...似乎我通过使用 for 循环使它变得更难了。谢谢!

标签: ios swift xcode for-loop asynchronous


【解决方案1】:

应避免在循环内调用异步函数。假设checkRoom() 方法在内部进行 API 调用。在这种情况下,将为所有房间运行循环,并且无论您何时收到每个请求的响应,所有房间的 API 请求都将排队。

理想情况下,您应该用递归替换循环。在函数内部调用checkRoom(),我们称之为mainFunction(),然后等待响应。如果您不符合加入房间的标准,则递归调用您的mainFunction(),这将调用checkRoom() 函数。像这样的:

var rooms: Array<Room> = []
var currentRoomIndex: Int = 0

func mainFunction() {

        checkRoom() { // async func
            let room = rooms[currentRoomIndex]
            if room.player.count == 1 {
                join(room)
                joined = true
                break
            } else {
                currentRoomIndex += 1
                mainFunction()
            }
        }
}

另一种方法是将您对 checkRoom() 函数的所有调用(可能是 API 请求)添加到队列中,一旦您的房间加入标准满足,停止队列中仍待处理的任务/请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 2013-02-16
    • 2020-07-03
    相关资源
    最近更新 更多