비동기식/대기 동작 - 비동기 코드를 작성하는 새로운 방법
7857 단어 developmentmobileiosswift
비동기 코드를 작성하는 새로운 방법
async/await가 해결할 수 있는 다섯 가지 주요 문제는 다음과 같다.
비동기식/대기 및 프로세서 완료
우선, 우리는 전통적으로 완성 처리 프로그램 작성 함수를 어떻게 사용하는지 보여 드리겠습니다.모든 사람이 이런 방법을 잘 안다.
오해하지 마라. 이것은 처리 프로그램을 완성하여 함수를 작성하는 좋은 방법이다.여러 해 동안 우리는 줄곧 이렇게 해 왔다projects.Swift 코드에서, 완성 처리 프로그램은 일반적으로 함수가 되돌아온 후에 값을 돌려보낼 수 있도록 하는 데 사용된다.
그럼에도 불구하고, 스wift 컴파일러는 코드에 오류가 들어왔는지 이상한 상황을 확인하기가 쉽지 않다.
더 간결한 코드를 위해 NetworkManager라는 새 Swift 파일을 만들었습니다.이 서류에서, 우리는 우리의 요구를 처리하고 있다.우리의 사용자는name, 이메일,username의 구조입니다.
struct User: Codable {
let name: String
let email: String
let username: String
}
// MARK: fetch users with completion handler
func fetchUsersFirstExample(completion: @escaping (Result<[User], NetworkingError>) -> Void) {
let usersURL = URL(string: Constants.url)
guard let url = usersURL else {
completion(.failure(.invalidURL))
return
}
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let _ = error {
completion(.failure(.unableToComplete))
}
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
completion(.failure(.invalidResponse))
return
}
guard let data = data else {
completion(.failure(.invalidData))
return
}
do {
let users = try JSONDecoder().decode([User].self, from: data)
completion(.success(users))
} catch {
completion(.failure(.invalidData))
}
}
task.resume()
}
보시다시피 이곳에는 많은 일들이 일어났다.디버깅하기는 매우 어렵다. 사용자 데이터만 얻는 데 있어서 많은 오류 처리가 있었고, 우리는 결국 많은 코드를 얻었다.대부분의 프로그래머들은 프로젝트에 두 개의 이런 코드를 작성해야 하는데, 이것은 매우 중복되고 보기 흉하게 변할 것이다.ViewController에서swift 파일에서, 우리는 하나의 테이블 보기에 데이터를 표시하기로 결정했기 때문에, 우리는 테이블 보기를 만들고 그 데이터 원본에 부합하도록 만들었다.일단 우리가 이 함수를 호출하기로 결정하면, 그것은 다음과 같다.
//MARK: 1. example -> with completion handlers
private var users = [User]()
private func getUsersFirstExample() {
NetworkManager.shared.fetchUsersFirstExample { [weak self] result in
guard let weakself = self else { return }
switch result {
case .success(let users):
DispatchQueue.main.async {
weakself.users = users
weakself.tableView.reloadData()
}
case .failure(let error):
print(error)
}
}
}
비동기 함수 정의 및 호출
다른 한편, 다음은 async/await를 사용하여 함수를 작성하는 방법으로 상술한 예시의 모든 조작을 완성할 수 있다.
//MARK: fetch users with async/await using Result type
func fetchUsersSecondExample() async -> Result<[User], NetworkingError> {
let usersURL = URL(string: Constants.url)
guard let url = usersURL else {
return .failure(.invalidURL)
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
let users = try JSONDecoder().decode([User].self, from: data)
return .success(users)
}
catch {
return .failure(.invalidData)
}
}
비동기 함수는 실행하는 도중에 멈출 수 있는 특수한 함수이다.이것은 동기화 함수와 반대로, 동기화 함수는 완성될 때까지 운행하거나, 오류를 던지거나, 영원히 돌아오지 않는다.우리는 async와 await 두 개의 키워드를 사용합니다.
우리는 async 키워드를 사용하여 컴파일러에게 코드가 언제 비동기적인지 알려 줍니다.wait 키워드를 사용하면 컴파일러에게 데이터나 오류가 돌아올 때까지 일시 정지 함수를 선택할 수 있음을 알려 줍니다.C# 및 Javascript와 같은 다른 언어와 같이 함수의 스레드를 잠금 해제할 수 있는 위치를 나타냅니다.
URLSession과 같은 Swift API도 비동기적입니다.
그러나 우리는 비동기적인 상하문(예를 들어 UIKit 기반 보기 컨트롤러)에서 비동기적인 표시가 있는 함수를 어떻게 호출합니까?
우리가 해야 할 일은 호출을 비동기 클립에 포장하는 것이다. 이것은 반대로 임무를 만들 것이다. 우리는 그 중에서 비동기 호출을 실행할 수 있다. 아래와 같다.
//MARK: 2. example -> async/await with Result type
private func getUsersSecondExample() {
async {
let result = await NetworkManager.shared.fetchUsersSecondExample()
switch result {
case .success(let users):
DispatchQueue.main.async {
self.users = users
self.tableView.reloadData()
}
case .failure(let error):
print(error)
}
}
}
결과 유형은 Swift 5.0에 도입되었으며 이 솔루션의 이점은 완료 프로세스를 개선하는 것입니다.물론 Swift 5.5에 async/await가 도입되었기 때문에 그것들은 그다지 중요하지 않게 변했다.
그러나 그것은 결코 쓸모가 없는 것이 아니다. 왜냐하면 그것은 여전히 결과를 저장하는 가장 좋은 방법이기 때문이다.
다음은 결과 유형을 사용하지 않고 async/await를 사용하는 또 다른 예입니다. 이것은 더욱 간결한 방법입니다.
//MARK: fetch users with async/await third example, without Result type
func fetchUsersThirdExample() async throws -> [User]{
let usersURL = URL(string: Constants.url)
guard let url = usersURL else { return [] }
let (data, _) = try await URLSession.shared.data(from: url)
let users = try JSONDecoder().decode([User].self, from: data)
return users
}
ViewController에서 비동기 함수를 호출합니다.swift 파일:override func viewDidLoad() {
super.viewDidLoad()
configureTableView()
async {
let users = await getUsersThirdExample()
guard let users = users else { return }
self.users = users
self.tableView.reloadData()
}
}
//MARK: 3. example -> async/await without Result type
private func getUsersThirdExample() async -> [User]? {
do {
let result = try await NetworkManager.shared.fetchUsersThirdExample()
return result
} catch {
// handle errors
}
return nil
}
상술한 예시에서 우리가 도,try,catch에서 Swift의 기본 오류 처리를 사용할 수 있는 가장 좋은 점이 하나 더 있다. 비동기 호출을 실행할 때도 마찬가지다.두 가지 예에서 보듯이 보존 주기를 피하기 위해 약한 셀프 캡처가 없고, 주 라인에서 UI를 업데이트할 필요가 없습니다. 왜냐하면 이 문제를 처리하기 위해 주 참여자 (@mainacctor) 가 있기 때문입니다. (Swift의 새로운 병렬 모드를 사용할 때만 주 참여자에 접근할 수 있습니다.)
봐라, 이것은 우리의 결과다.
결론
Async/await는 Swift 병렬 옵션의 일부분일 뿐입니다.애플의 SDK는 그것들을 대량으로 사용하기 시작했다.이것은 Swift로 비동기 코드를 작성하는 새로운 방법을 제공했다.유일한 단점은 오래된 운영체제 버전과 호환되지 않는다는 것이다. 우리는 여전히 async/await를 사용하지 않은 다른 코드와 상호작용을 해야 한다.이 문서는 Swift의 비동기식 프로그래밍을 이해하는 데 도움이 되었으면 합니다.
이 모델에 대한 정보나 Swift concurrency가 도입한 모든 정보를 알고 싶다면 애플의 공식 사이트를 방문해 문서를 읽어 보세요.또한 다음과 같은 유용한 링크를 볼 수 있습니다.
Swift Programming language - Concurrency
Reference
이 문제에 관하여(비동기식/대기 동작 - 비동기 코드를 작성하는 새로운 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/barrage/async-await-operations-a-new-way-of-writing-asynchronous-code-5050텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)