nextTick

by aloerina

HTML

<a id="btn" style="display:block;margin:20px 0;width:60px;text-align:center;padding:12px 20px;border-radius:4px;border-style:none;background-color:#5487e5;color:#fff;font-weight:bold;box-shadow:1px 1px 10px #ddd;cursor:pointer;">実 行</a>

<h3>contents</h3>
<div id="content"></div>

<h3>log</h3>
<div id="log" style="font-size:12px"></div>

JavaScript

// prepare
let logIndex = 1;
reset();
document.querySelector('#btn').addEventListener('click', execute);

// util
function macroTask(fn) {
  setTimeout(fn, 0);
}

function microTask(fn) {
  Promise.resolve().then(fn);
}

function log(_message) {
  const message = `${logIndex++}: ${_message} (${performance.now()})`;
  console.log(message);
  const logArea = document.querySelector('#log');
  const log = document.createElement('p');
  log.innerText = message;
  logArea.appendChild(log);
}

function reset() {
  const contentArea = document.querySelector('#content');
  const logArea = document.querySelector('#log');
  while (contentArea.firstChild) contentArea.removeChild(contentArea.firstChild);
  while (logArea.firstChild) logArea.removeChild(contentArea.firstChild);
  contentArea.innerHtml = '';
}

function execute() {
  logIndex = 1;
  reset();
	// execute nextTick(macroTask)
	macroTask(() => log('call from macroTask (use setTimeout)'));
	// execute nextTick(microTask)
	microTask(() => log('call from microTask (use Promise)'));

	// render DOM by sync logic
	const contentArea = document.querySelector('#content');
	const div = document.createElement('div');
	div.style.padding = '12px 20px';
	div.style.backgroundColor = '#efefef';
	div.style.fontSize = '12px';
	div.innerText = `content updated !`;
	contentArea.appendChild(div);
	log('rendering logic is finished'); 

	// do something by sync logic
	const startTime = Date.now();
	while (Date.now() - startTime < 1000) {}
	log('something logic is finished');
}