Concurrency

Defining and Calling Asynchronous Functions

We use async keyword in place of before return arrow in function definition to make a function as a Asynchronour Function.

Just like throwing functions, and wa wanna a function is both asynchronous and throwing, we write async before throwing.

func listPhotos(inGallery name: String) async -> [String] {
    let result = // ... some asynchronous networking code ...
    return result
}

func listPhotos2(inGallery name: String) async throws -> [String] {
    let result = // ... some asynchronous networking code ...
    return result
}

And we use await keyword to describe we need to wait a return value whthin a function untill it returns.

let photoNames = await listPhotos(inGallery: "Summer Vacation")
let sortedNames = photoNames.sorted()
let name = sortedNames[0]
let photo = await downloadPhoto(named: name)
show(photo)

await will suspend the code that is excuting.

Calling Asynchronous Functions in Parallel

If we want to call a function in parallel, just like dispatch.async, we don’t want a function to suspend the code, but we need the async characteristic, we can use async keyword to decorate a value.

async let firstPhoto = downloadPhoto(named: photoNames[0])
async let secondPhoto = downloadPhoto(named: photoNames[1])
async let thirdPhoto = downloadPhoto(named: photoNames[2])

let photos = await [firstPhoto, secondPhoto, thirdPhoto]
show(photos)

The example above shows a circumstance just like using dispatch,group.

Tasks and Task Groups

There are interesting thing that is the task in swift.

We can incoporate Task and async there two characteristics to do a asynchronous task surprisingly easy.

We can handle a group of tasks even.

await withTaskGroup(of: Data.self) { taskGroup in
    let photoNames = await listPhotos(inGallery: "Summer Vacation")
    for name in photoNames {
        taskGroup.async { await downloadPhoto(named: name) }
    }
}
let newPhoto = // ... some photo data ...
let handle = Task {
    return await add(newPhoto, toGalleryNamed: "Spring Adventures")
}
let result = await handle.value

And we can control each task by change its status.

Actors

Actor is just like Class, we can define a new actor with properties and functions by using actor keyword

actor TemperatureLogger {
    let label: String
    var measurements: [Int]
    private(set) var max: Int

    init(label: String, measurement: Int) {
        self.label = label
        self.measurements = [measurement]
        self.max = measurement
    }
}

But actor is much safer than class in asynchronous function since it only agree one operation on its state at a time.

And for its private property, we must use await to access it, which is called as actor isolation.

Let’s think!

你可能感兴趣的:(Concurrency)