Looking for a specific implementation for both sync and async recursive functions that could be used as a starting point to turn future recursive functions into flat iteration.
Below are two examples of recursive functions: Synchronous and Asynchronous.
What I am looking for is an implementation of both using a stack without recursion.
For example, maybe it would work like this:
var output = syncStack(myRecursiveFunctionTurnedIterative, [])
Or if that's not possible, then just a reimplementation of the two functions below using a stack, and that should be a good enough start. E.g.
var stack = []
function circularReferences(object, references, stack) {
  var output = {}
  if (object.__circularid__) return true
  Object.defineProperty(object, '__circularid__', { value: id++ })
  for (var key in object) {
    var value = object[key]
    if (value && typeof value == 'object') {
      console.log(value)
      stack.push(???)
      circularReferences()
      stack.pop()
      if (is) output[key] = '[Circular]'
    } else {
      output[key] = value
    }
  }
}
The reason for this question is, I have tried over the years to learn how to do this, but have never found a system that is (a) easy to remember how to do, and (b) practical.
Synchronous
var references = {}
var object = {
  a: {
    b: {
      c: {
        d: {
          e: 10,
          f: 11,
          g: 12
        }
      }
    }
  }
}
object.a.b.c.d.x = object
object.a.b.c.d.y = object.a.b
var id = 1
var x = circularReferences(object, references)
console.log(x)
function circularReferences(object, references) {
  var output = {}
  if (object.__circularid__) return true
  Object.defineProperty(object, '__circularid__', { value: id++ })
  for (var key in object) {
    var value = object[key]
    if (value && typeof value == 'object') {
      console.log(value)
      var is = circularReferences(value, references)
      if (is) output[key] = '[Circular]'
    } else {
      output[key] = value
    }
  }
}Asychronous
var items = [
  async1a,
  async1b,
  async1c
  // ...
]
asynca(items, function(){
  console.log('done')
})
function asynca(items, callback) {
  var i = 0
  function next() {
    var item = items[i++]
    if (!item) return callback()
    item(next)
  }
}
function async1a(callback) {
  // Some stuff...
  setTimeout(function(){
    if (true) {
      var items = [
        async2a,
        // ...
      ]
      asynca(items, callback)
    } else {
      callback(null, true)
    }
  }, 200)
}
function async1b(callback) {
  // Some stuff...
  setTimeout(function(){
    if (true) {
      var items = [
        async2a,
        // ...
      ]
      asynca(items, callback)
    } else {
      callback(null, true)
    }
  }, 200)
}
function async1c(callback) {
  // Some stuff...
  setTimeout(function(){
    if (true) {
      var items = [
        async2a,
        // ...
      ]
      asynca(items, callback)
    } else {
      callback(null, true)
    }
  }, 200)
}
function async2a(callback) {
  return callback()
}For example, that may start looking something like:
var items = [
  async1a,
  async1b,
  async1c
  // ...
]
asynca(items, function(){
  console.log('done')
}, [])
function asynca(items, callback, stack) {
  var i = 0
  function next() {
    var item = items[i++]
    if (!item) return callback()
    stack.push(item)
  }
}
But that's where I get lost. Not sure how to pass around the stack and how the functions should be setup in general.
Wondering how to in practice write those as non-recursive functions. I've seen Way to go from recursion to iteration but they are all very theoretical.
 
     
     
     
    