$.microtask.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. var global = require('./$.global')
  2. , macrotask = require('./$.task').set
  3. , Observer = global.MutationObserver || global.WebKitMutationObserver
  4. , process = global.process
  5. , Promise = global.Promise
  6. , isNode = require('./$.cof')(process) == 'process'
  7. , head, last, notify;
  8. var flush = function(){
  9. var parent, domain, fn;
  10. if(isNode && (parent = process.domain)){
  11. process.domain = null;
  12. parent.exit();
  13. }
  14. while(head){
  15. domain = head.domain;
  16. fn = head.fn;
  17. if(domain)domain.enter();
  18. fn(); // <- currently we use it only for Promise - try / catch not required
  19. if(domain)domain.exit();
  20. head = head.next;
  21. } last = undefined;
  22. if(parent)parent.enter();
  23. };
  24. // Node.js
  25. if(isNode){
  26. notify = function(){
  27. process.nextTick(flush);
  28. };
  29. // browsers with MutationObserver
  30. } else if(Observer){
  31. var toggle = 1
  32. , node = document.createTextNode('');
  33. new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new
  34. notify = function(){
  35. node.data = toggle = -toggle;
  36. };
  37. // environments with maybe non-completely correct, but existent Promise
  38. } else if(Promise && Promise.resolve){
  39. notify = function(){
  40. Promise.resolve().then(flush);
  41. };
  42. // for other environments - macrotask based on:
  43. // - setImmediate
  44. // - MessageChannel
  45. // - window.postMessag
  46. // - onreadystatechange
  47. // - setTimeout
  48. } else {
  49. notify = function(){
  50. // strange IE + webpack dev server bug - use .call(global)
  51. macrotask.call(global, flush);
  52. };
  53. }
  54. module.exports = function asap(fn){
  55. var task = {fn: fn, next: undefined, domain: isNode && process.domain};
  56. if(last)last.next = task;
  57. if(!head){
  58. head = task;
  59. notify();
  60. } last = task;
  61. };