SOURCE

class BTree{
  constructor(value, left=null, right=null) {
      this.value = value;
      this.left = left;
      this.right = right;
  }
  
  *preOrder() {
    yield console.log(this.value);
    if (this.left) {
        yield *this.left.preOrder();
    }
    if (this.right) {
        yield *this.right.preOrder();
    }
  }
  
  *inOrder() {
    if(this.left){
      yield *this.left.inOrder();
    }
    yield console.log(this.value);
    if(this.right){
      yield *this.right.inOrder();
    }
  }
  
  *postOrder() {
    if(this.left){
      yield *this.left.postOrder();
    }
    if(this.right){
      yield *this.right.postOrder();
    }
    yield console.log(this.value);
  }
}

function run(genFuc, initialValue) {
  const gen = genFuc(initialValue);
  iterate(gen);

  function iterate(gen) {
    step();
    function step(arg, isError) {
      const {value: express, done} = isError ? gen.throw(arg) : gen.next(arg); 
      let response;
      if (!done) {
        if (typeof express === 'function') {
          response = express();  
        } else {
          response = express;    
        }
        Promise.resolve(response).then(step, err => step(err, true));
      }
    }
  }
}

let tree = new BTree('a', 
new BTree('b', new BTree('c'), new BTree('d')),
new BTree('e'));

var preorder = tree.preOrder.bind(tree);
run(preorder);

// var inorder = tree.inOrder.bind(tree);
// run(inorder);

// var postorder = tree.postOrder.bind(tree);
// run(postorder);
console 命令行工具 X clear

                    
>
console