Skip to content

Instantly share code, notes, and snippets.

@zyf0330
Last active July 6, 2021 10:09
Show Gist options
  • Save zyf0330/7f38b772a9f12d4fb7596a6138a17985 to your computer and use it in GitHub Desktop.
Save zyf0330/7f38b772a9f12d4fb7596a6138a17985 to your computer and use it in GitHub Desktop.
construct two-way dependency map to execute by order
'use strict'
function resolver(o) {
return new Promise((res) => {
setTimeout(() => {
console.log(Date.now(), 'prepare end', o.service)
res()
}, 1000)
})
}
let i = 0
const o1 = { service: 'o1', dependOn: [], dependBy: [] }
const o5 = { service: 'o5', dependOn: [], dependBy: [] }
const o2 = { service: 'o2', dependOn: [o1, o5], dependBy: [] }
const o6 = { service: 'o6', dependOn: [o2], dependBy: [] }
const o3 = { service: 'o3', dependOn: [o2, o6], dependBy: [] }
const o4 = { service: 'o4', dependOn: [o2, o6], dependBy: [] }
const registry = {
o1,
o2,
o3,
o4,
o5,
o6,
}
let dependencyMap = {}
function calculateDependencyMap() {
const tempDependencyMap
= Object.entries(registry)
.reduce((dependencyMap, [serviceName, o]) => {
dependencyMap[serviceName] = {
service: serviceName,
dependOn: o.dependOn.map(({ service }) => service),
dependBy: [],
}
return dependencyMap
}, {})
Object.values(tempDependencyMap).forEach((tempDependency) => {
const dependency = tempDependency
dependency.dependOn = tempDependency.dependOn.map((serviceName) => tempDependencyMap[serviceName])
dependency.dependOn.forEach(({ service: serviceName }) => {
tempDependencyMap[serviceName].dependBy.push(dependency)
})
}, tempDependencyMap)
dependencyMap = tempDependencyMap
}
function resolveActionsByDependencyOrder(order) {
const actionsMap = {}
const resolveRecursive = (dependencies) => {
dependencies.forEach((dependency) => {
if (dependency.service in actionsMap === false) {
if (dependency[order === "topToDown" ? "dependOn" : "dependBy"].every(({ service }) => service in actionsMap)) {
const dependencyPromises = dependency[order === "topToDown" ? "dependOn" : "dependBy"].map(({ service }) => actionsMap[service])
const o = dependencyMap[dependency.service]
actionsMap[dependency.service] = Promise.all(dependencyPromises).then(() => resolver(o))
}
}
resolveRecursive(dependency[order === "topToDown" ? "dependBy" : "dependOn"])
})
}
resolveRecursive(Object.values(dependencyMap).filter((dependency) => dependency[order === "topToDown" ? "dependOn" : "dependBy"].length === 0))
return Object.values(actionsMap)
}
calculateDependencyMap()
resolveActionsByDependencyOrder()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment