Hi There,
The proper way is to be a bit more transparent and avoid writing too much code on the function node. This way other people looking at your flow can figure out what is happening. You don't want to manage all your async calls. Let Node RED do it for you! ;)
This is the way to do all the http calls you want and wait for data to complete. Copy and paste this flow:
[{"id":"ce5f98f9.31a068","type":"function","name":"Wait for all workers to finish","func":"context.data = context.data || {};\n\nswitch (msg.topic) {\n case \"task1\":\n context.data.task1 = msg.payload;\n msg = null;\n break;\n case \"task2\":\n context.data.task2 = msg.payload;\n msg = null;\n break;\n \n default:\n msg = null;\n \tbreak;\n\n}\n\nif(context.data.task1 != null && context.data.task2 != null ) {\n\tmsg2 = {};\n\t//do something with data.\n\t// Task 1 is in context.data.task1,\n\t// Task 2 is in context.data.task2\n context.data=null; //delete context\n\treturn msg2;\n} else return msg;","outputs":1,"noerr":0,"x":815,"y":306,"z":"ec8bd99d.137428","wires":[["1375fff2.ec8a"]]},{"id":"e7e548e2.181ab8","type":"function","name":"add topic \"task1\"","func":"msg.topic = \"task1\";\nreturn msg\n\n","outputs":1,"noerr":0,"x":564,"y":186,"z":"ec8bd99d.137428","wires":[["ce5f98f9.31a068"]]},{"id":"7b2c5afd.84d3a4","type":"http request","name":"","method":"GET","ret":"txt","url":"","x":307,"y":177,"z":"ec8bd99d.137428","wires":[["e7e548e2.181ab8"]]},{"id":"34b4cae2.cb4b36","type":"function","name":"add topic \"task2\"","func":"msg.topic = \"task2\";\nreturn msg\n\n","outputs":1,"noerr":0,"x":553,"y":347,"z":"ec8bd99d.137428","wires":[["ce5f98f9.31a068"]]},{"id":"ff3b8a05.00c478","type":"http request","name":"","method":"GET","ret":"txt","url":"","x":332,"y":334,"z":"ec8bd99d.137428","wires":[["34b4cae2.cb4b36"]]},{"id":"dbd9de7f.24262","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":161,"y":253,"z":"ec8bd99d.137428","wires":[["7b2c5afd.84d3a4","ff3b8a05.00c478"]]},{"id":"1375fff2.ec8a","type":"debug","name":"","active":true,"console":"false","complete":"false","x":1112,"y":299,"z":"ec8bd99d.137428","wires":[]}]
This is what is happening here: When you hit the inject node each of the http nodes are called. A small function node adds a "topic" element that will be used by a second function node that will wait for all topics (task1, task2, taskn) to complete. Once they are all complete you can agregate the data and do your magic. If you read the http node you can set up the url dynamically with moustache strings and the "msg.url" element in the input. ;)
Hopefully this helps.