Callback hell was never about promises, but callbacks (!) which would require a third-party library or some gymnastics to implement control flow. Promises and async/await both solve it reasonably well. The problem presented can be rewritten as:
Promise.all([
doA().then(a => doC(a).then(c => [a, c])),
doB().then(b => doD(b), b_; return b; })
]).then(([a, c], b) => doE(c, a, b))
No need for `new Promise(resolve => ...)`. Or with async/await:
const [a, b] = Promise.all([doA(), doB()])
doD(b)
const c = await doC(a)
doE(c, a, b)
Is it worth introducing the complexity of visual programming to solve this 'problem'? I have a much harder time understanding the graph than the code.