var global = require('./$.global') , macrotask = require('./$.task').set , Observer = global.MutationObserver || global.WebKitMutationObserver , process = global.process , Promise = global.Promise , isNode = require('./$.cof')(process) == 'process' , head, last, notify; var flush = function(){ var parent, domain, fn; if(isNode && (parent = process.domain)){ process.domain = null; parent.exit(); } while(head){ domain = head.domain; fn = head.fn; if(domain)domain.enter(); fn(); // <- currently we use it only for Promise - try / catch not required if(domain)domain.exit(); head = head.next; } last = undefined; if(parent)parent.enter(); }; // Node.js if(isNode){ notify = function(){ process.nextTick(flush); }; // browsers with MutationObserver } else if(Observer){ var toggle = 1 , node = document.createTextNode(''); new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new notify = function(){ node.data = toggle = -toggle; }; // environments with maybe non-completely correct, but existent Promise } else if(Promise && Promise.resolve){ notify = function(){ Promise.resolve().then(flush); }; // for other environments - macrotask based on: // - setImmediate // - MessageChannel // - window.postMessag // - onreadystatechange // - setTimeout } else { notify = function(){ // strange IE + webpack dev server bug - use .call(global) macrotask.call(global, flush); }; } module.exports = function asap(fn){ var task = {fn: fn, next: undefined, domain: isNode && process.domain}; if(last)last.next = task; if(!head){ head = task; notify(); } last = task; };