Promise chaining demo with Recursive promises

Ref: https://stackoverflow.com/questions/41905839/fire-promise-all-once-all-nested-promises-have-resolved/ getObject() method is used to generate an object with random number of elements in kids property. each kid object can internally have random number of kids. (3 level of nesting.) Promise chaining is used to resolve all nested objects before printing the complete object hierarchy

by Vivek Athalye

HTML

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<button id='runit'>Run</button>
<button id='clear'>Clear</button>
<pre id="result">

</pre>

JavaScript

function getItem(id) {
	log("getItem(): " + id);
  return somePromise(id) // fetch and object for given id
    .then(snapshot => snapshot.val)
    .then(val => Promise.all((val.kids || []).map(getItem))
      .then(kidsVals => val.replies = kidsVals)
      .then(() => val)
    );
}

// this method is similar to executing an AJAX request. It returns a JSON object after random (1000 to 3000) milliseconds
function somePromise(id) {
	return new Promise((resolve, reject) => {
		let ret = getObject(id)
		log("somePromise(): " + JSON.stringify(ret));
  	setTimeout(function(){
    	resolve(ret)
    }, getRandomInt(10, 30, true) *100) // between 1 to 3 seconds, inclusive
  });
}

// create an object with id and random number of kids
function getObject(id) {
	let ret = { }
	ret.val = {}
	ret.val.id = "id_" + id;
  let len = getRandomInt(0,3, true) // number of kids: 0 to 3 
  if(id.length > 3 || len == 0) { // checking id.length to avoid too much of nesting
    return ret;
  }

	ret.val.kids = []
  for(i=1; i<=len; i++) {
		ret.val.kids.push(id + "_" + i) // push kid ids only
  }
  return ret
}

function getRandomInt(min, max, inclusive) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + (inclusive? 1 : 0))) + min;
}

function log(str) {
	let res = $('#result')
	res.text(res.text() + str + '\n')
}

$('#runit').click(function() {
	getItem(1).then(o => log(JSON.stringify(o, null, '  ')))
})

$('#clear').click(function() {
	$('#result').text('')
})