How do you work with Asynchronous functions, recursively?



  • I am currently working on FLEX and have to call a web services. once I have the result, I have to call the web service again, with the previous result as the input.

    A compounding problem, is that the service might return multiple results, and I have to call the service again with each of the results as the input. Lastly, i need the results to be in a hierarchical array collection, with each result as the child of the input to the web service.

    If it were a synchronous function, it would have been very easy, but I have spent half a day trying to come up with something elegant for the web service.

    I ended up with having two arrays, one for the input, and one for the results. Every time I had one or more result, I would put it in the Input array and the results. I would then remove the first item from the input array and call the web service with it, and so on, till I finished all the inputs. Once I had all the results, I made a recursive function that would create the hierarchical tree, that I needed.

    This seems like a very hacky, WTF Solution.

    Is there any elegant and better solution? I am all ears.



  • Surely the method you use to call the webservice has a callback?

     



  • @dhromed said:

    Surely the method you use to call the webservice has a callback?

     


    And even if it doesnt, you could roll your own, mapping request ids to callback functions.



  • @dev3 said:

    This seems like a very hacky, WTF Solution. Is there any elegant and better solution? I am all ears.

    Use a task-based solution. Each service request is encapsulated in a task, which has a 'taskcomplete' callback, event, etc. This way you can start subtasks after a request has completed and only raise 'taskcomplete' once those subtasks have completed. Upon completion of a task, you return the subtree through the callback or event. This would easily allow you to construct your hierarchical array of results without having to manually track the contents of arrays.



  • I ended up with having two arrays, one for the input, and one for the results. Every time I had one or more result, I would put it in the Input array and the results. I would then remove the first item from the input array and call the web service with it, and so on, till I finished all the inputs. Once I had all the results, I made a recursive function that would create the hierarchical tree, that I needed.

    That's pretty good, in that it actually benefits from the asynchronous nature of web service calls; you're able to issue calls as fast as your "input array" (I would think of this as a "work queue") builds, which you would not be able to do if you faked up a synchronous wrapper and called it recursively.

    But it seems to me that if the results contain enough parent-child information to let you build the tree after collecting them all, you could just as easily build it on the fly as results come back. You wouldn't even need recursion for this; just create a parent node at the time you issue a service call, and every time you see a result come back for that parent, add it as a child node as well as slapping a reference to it onto the end of the work queue.

    The only tricky part is figuring out when you're done. But if instead of totally forgetting about a work queue item when you issue a service call for it, you could move it to a "results pending" queue, from which you delete items as you get back their results. Then you could simply stop issuing requests as soon as the work queue empties, and do your own completion processing (return to your caller if you're sync, issue a callback if you're async) as soon as both queues empty.

    You might even want to put some logic in there to move items from the pending queue back to the work queue under timeout and retry count control.


Log in to reply