extension Sequence {
/// An asynchronous sequence containing the same elements as this sequence,
/// but on which operations, such as `map` and `filter`, are implemented asynchronously.
@inlinable
public var async: AsyncSyncSequence<Self> {
AsyncSyncSequence(self)
}
}
/// An asynchronous sequence composed from a synchronous sequence.
///
/// Asynchronous lazy sequences can be used to interface existing or pre-calculated
/// data to interoperate with other asynchronous sequences and algorithms based on
/// asynchronous sequences.
///
/// This functions similarly to `LazySequence` by accessing elements sequentially
/// in the iterator's `next()` method.
@frozen
public struct AsyncSyncSequence<Base: Sequence>: AsyncSequence {
public typealias Element = Base.Element
@frozen
public struct Iterator: AsyncIteratorProtocol {
@usableFromInline
var iterator: Base.Iterator?
@usableFromInline
init(_ iterator: Base.Iterator) {
self.iterator = iterator
}
@inlinable
public mutating func next() async -> Base.Element? {
if !Task.isCancelled, let value = iterator?.next() {
return value
} else {
iterator = nil
return nil
}
}
}
@usableFromInline
let base: Base
@usableFromInline
init(_ base: Base) {
self.base = base
}
@inlinable
public func makeAsyncIterator() -> Iterator {
Iterator(base.makeIterator())
}
}
extension AsyncSyncSequence: Sendable where Base: Sendable { }
举例说明:
import Foundation
// 假设有一批待检测的域名
let domainList = ["example1.com", "example2.com", "usable-domain.com", "example3.com"]
// 模拟一个异步函数,用来检查单个域名是否可用
func checkDomainAvailability(_ domain: String) async -> Bool {
// 模拟网络请求的延迟
try? await Task.sleep(nanoseconds: 500_000_000) // 0.5秒延迟
// 假设域名以 "usable" 开头的是可用的
return domain.hasPrefix("usable")
}
// 扩展:使 Sequence 可以通过 `async` 属性生成异步序列
extension Sequence {
var async: AsyncSyncSequence<Self> {
AsyncSyncSequence(self)
}
}
// 异步检查域名的可用性
Task {
for await domain in domainList.async {
if await checkDomainAvailability(domain) {
print("\(domain) 是第一个可用的域名")
break // 找到第一个可用域名后立即停止
} else {
print("\(domain) 不可用")
}
}
}
-
for await 循环:逐个异步遍历 domainList 中的域名。
-
await checkDomainAvailability(domain):异步检查域名的可用性。
-
break:在找到第一个可用域名后,立即退出循环,不再继续检查剩余的域名。