The Problem
Given a number of asynchronously loaded dependencies, I want to trigger some code only after all dependencies are finished loading. As a simple example, consider the following pseudo-code:
bool firstLoaded = false, secondLoaded = false, thirdLoaded = false;
function loadResourceOne() {
// Asynchronously, or in a new thread:
HTTPDownload("one.txt");
firstLoaded = true;
if (secondLoaded && thirdLoaded) {
allLoaded();
}
}
function loadResourceTwo() {
// Asynchronously, or in a new thread:
HTTPDownload("two.txt");
secondLoaded = true;
if (firstLoaded && thirdLoaded) {
allLoaded();
}
}
function loadResourceThree() {
// Asynchronously, or in a new thread:
HTTPDownload("three.txt");
thirdLoaded = true;
if (firstLoaded && secondLoaded) {
allLoaded();
}
}
function allLoaded() {
Log("Done!");
}
/* async */ loadResourceOne();
/* async */ loadResourceTwo();
/* async */ loadResourceThree();
What I'm Looking For
This is a problem that I've found myself having to solve repeatedly in different languages and in different contexts. However every time I find myself using the tools provided by the language to hack together some simple solution, like returning each asynchronous resource as a Promise in JavaScript then using Promise.all()
-- or loading each resource in its own thread in Python then using threads.join()
I'm trying to find a design pattern that solves this problem in the general case. The best solution should meet two criteria:
- Can be applied to any language that supports asynchronous operations
- Minimizes repetition of code (note that in my simple example the line
allLoaded();
was repeated three times, and theif
statement preceding it was practically repeated, and wouldn't scale well if I need a fourth or fifth dependency) - Runs the final callback as soon as possible when all resources are loaded -- this one is hopefully obvious, but solutions like "check that all are loaded every 5 seconds" aren't acceptable
I tried flipping through the index of the Gang of Four's Design Patterns, but the few pattern names that jumped out at me as possible leads turned out to be unrelated.