How can I improve dependencies here where Employee object in for loop depends on getAddress api to get employee address and keeps entire for loop on wait state until getAddress is finished?
I would like to make getAddress Api call concurrent and move to next forEach employee record without waiting for getAdress to return. And finally return all [Employee] array after all requests finished.
func employees() async throws -> [Employee] {
var employees = [Employee]()
let employeeInfoArr: [EmployeeInfo] = try await getEmployeeInfoRecords()
employeeInfoArr.forEach { employeeInfo in
let employeeAddress = try await getAddress(for: employeeInfo.name) // 0...3 seconds each for request
let employee = Employee(name: employeeInfo.name, address: employeeAddress) // ForEach waits until we receive response and then move to next request
employee.name.append(employee)
}
return employees
}
It would be nice if whatever API backing getAddress(..) offered a form that could return addresses for multiple employees in one query. If that’s not available, but the API supports your method using potentially dozens of concurrent connections, I’d expect a nice speed boost using withThrowingTaskGroup(of:returning:body:):
func employees() async throws -> [Employee] {
let employeeInfoArr: [EmployeeInfo] = try await getEmployeeInfoRecords()
return try await withThrowingTaskGroup(of: Employee.self) { taskGroup in
employeeInfoArr.forEach { employeeInfo in
taskGroup.addTask {
let employeeAddress = try await getAddress(for: employeeInfo.name)
return Employee(name: employeeInfo.name, address: employeeAddress)
}
}
var employees = [Employee]()
for try await employee in taskGroup {
employees.append(employee)
}
return employees
}
}
*It's important to note the results from employees() will not be in the same order as the elements of employeeInfoArr since the task group's tasks are ran concurrently, then collected according to which tasks finished processing first.
Also, is it possible to limit the number of active tasks in a taskgroup like semaphore so that the next submitted tasks are executed after the submitted_tasks_count < allowed_task_limit_count?