multithreading - Return from asynchronous request in for loop -
i’m trying data restapi, i’m getting array of integers (which id’s other users), want loop through array , download data other customers. simplified version of code show below.
func asyncfunc(completion: (something:[int])->void){ //get json array asynchonous restapi let jsonarray = [1,2,3,4,5] var resultingarray:[int] = [] mything in jsonarray{ anotherasyncfunc(mything, completion: { (somethingelse) -> void in resultingarray.append(somethingelse) }) } } func anotherasyncfunc(data:int, completion: (somethingelse:int)->void){ //get more jsondata restapi/data let myloadeddata:int = data*13356 completion(somethingelse: myloadeddata) }
how make asyncfunc
return array items has gotten second (inner) async request.
i have tried getting count of array first requested rest api , “blocking” ui thread using while loop see if “new” array has collected data (the count equal count of first requested array). has 2 major disadvantages, blocks ui thread , further more, fail , crash app if data connection gets broken while i’m getting data other users (the inner async request), cause while loop never complete.
my question how use completion handler return data should return without blocking main thread and/or having worry badly timed data connection losses.
you can use dispatch group notification. create dispatch group, enter group each item in array, exit in completion handler of anotherasyncfunc
asynchronous process, , create notification trigger final completion
closure when of dispatch_group_enter
calls have been offset corresponding dispatch_group_leave
call:
func asyncfunc(completion: (something:[int])->void){ //get json array asynchonous restapi let jsonarray = [1,2,3,4,5] var resultingarray:[int] = [] let group = dispatch_group_create() mything in jsonarray { dispatch_group_enter(group) anotherasyncfunc(mything) { somethingelse in resultingarray.append(somethingelse) dispatch_group_leave(group) } } dispatch_group_notify(group, dispatch_get_main_queue()) { completion(something: resultingarray) } }
note, want make sure synchronize updates resultingarray
anotherasyncfunc
performing. easiest way make sure dispatches updates main queue (if rest api doesn't already).
func anotherasyncfunc(data:int, completion: (somethingelse:int)->void){ //get more jsondata restapi/data asynchronously let myloadeddata:int = data*13356 dispatch_async(dispatch_get_main_queue()) { completion(somethingelse: myloadeddata) } }
this example. can use whatever synchronization mechanism want, make sure synchronize updates on resultingarray
accordingly.
Comments
Post a Comment