Это прекрасный повод для топологической сортировки .
Удаление терминологии компонентов, схем и конфигураций, что у вас есть объекты (различного рода), которые зависят от других существующих объектов первый. Топологическая сортировка создаст порядок, который имеет только прямые зависимости (при условии, что у вас нет циклических зависимостей, в этом случае это невозможно).
Но сложность заключается в том, что у вас есть информация о зависимостях в разных направлениях. , Компонент должен быть создан до его схемы. Схема должна быть создана после схем, от которых она зависит. Не исключено, что эти схемы могут принадлежать и другим компонентам, которые также должны быть созданы.
Первый шаг - написать функцию, которая принимает объект и возвращает набор отношений зависимости, обнаруживаемых самим объектом. , Поэтому мы хотим, чтобы dependencyRelations(object1
дал что-то вроде [[object1, object2], [object3, object1], [object1, object4]]
. Где object1
зависит от object2
существующего. (Обратите внимание, что object1
будет в каждой паре, но может быть первым или вторым.)
Если у каждого объекта есть метод с именем uniqueName
, который однозначно идентифицирует его, то мы можем написать метод, который работает примерно так: (извините, весь код был набран здесь и не тестировался, возможно, есть синтаксические ошибки, но идея верна):
function dependencyInfo (startingObject) {
const nameToObject = {};
const dependencyOf = {};
const todo = [startingObject];
const visited = {};
while (0 < todo.length) {
let obj = todo.pop();
let objName = obj.uniqueName();
if (! visited[ objName ]) {
visited[ objName ] = true;
nameToObject[objName] = obj;
dependencyRelations(obj).forEach((pair) => {
const [from, to] = pair;
// It is OK to put things in todo that are visited, we just don't process again.
todo.push(from);
todo.push(to);
if (! dependencyOf[from.uniqueName()]) {
dependencyOf[from.uniqueName()] = {}
}
dependencyOf[from.uniqueName()] = to.uniqueName();
});
}
}
return [nameToObject, dependencyOf];
}
Эта функция построит граф зависимостей. Но нам все еще нужно выполнить топологическую сортировку, чтобы сначала получить зависимости.
function objectsInOrder (nameToObject, dependencyOf) {
const answer = [];
visited = {};
// Trick for a recursive function local to my environment.
let addObject = undefined;
addObject = function (objName) {
if (! visited[objName]) {
visited[objName] = true; // Only process once.
// Add dependencies
Object.keys(dependencyOf[objName]).forEach(addObject);
answer.push(nameToObject[objName]);
}
};
Object.keys(dependencyOf).forEach(addObject);
return answer;
}
И теперь у нас есть массив объектов, каждый из которых зависит только от предыдущих. Отправьте это, и на другом конце вы просто раздуваете каждый объект по очереди.