Source: schedule.js

/** @module decor/schedule */
define(["./features"], function (has) {
	"use strict";

	/**
	 * Calls a function at the end of microtask.
	 * @function module:decor/schedule
	 * @param {Function} callback The function to call at the end of microtask.
	 */

	/* global setImmediate */
	var inFlight,
		SCHEDULEID_PREFIX = "_schedule",
		seq = 0,
		uniqueId = Math.random() + "",
		callbacks = {},
		pseudoDiv = has("mutation-observer-api") && document.createElement("div");
	function runCallbacks() {
		for (var anyWorkDone = true; anyWorkDone;) {
			anyWorkDone = false;
			for (var id in callbacks) {
				var callback = callbacks[id];
				delete callbacks[id];
				callback();
				anyWorkDone = true;
			}
		}
		inFlight = false;
	}
	if (has("mutation-observer-api")) {
		pseudoDiv.id = 0;
		new MutationObserver(runCallbacks).observe(pseudoDiv, {attributes: true});
	} else if (!has("setimmediate-api")) {
		window.addEventListener("message", function (event) {
			if (event.data === uniqueId) {
				runCallbacks();
			}
		});
	}
	return function (callback) {
		var id = SCHEDULEID_PREFIX + seq++;
		callbacks[id] = callback;
		if (!inFlight) {
			has("mutation-observer-api") ? ++pseudoDiv.id :
				has("setimmediate-api") ? setImmediate(runCallbacks) :
				window.postMessage(uniqueId, "*");
			inFlight = true;
		}
		return {
			remove: function () {
				delete callbacks[id];
			}
		};
	};
});