index.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict';
  2. var Mutation = global.MutationObserver || global.WebKitMutationObserver;
  3. var scheduleDrain;
  4. if (process.browser) {
  5. if (Mutation) {
  6. var called = 0;
  7. var observer = new Mutation(nextTick);
  8. var element = global.document.createTextNode('');
  9. observer.observe(element, {
  10. characterData: true
  11. });
  12. scheduleDrain = function () {
  13. element.data = (called = ++called % 2);
  14. };
  15. } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {
  16. var channel = new global.MessageChannel();
  17. channel.port1.onmessage = nextTick;
  18. scheduleDrain = function () {
  19. channel.port2.postMessage(0);
  20. };
  21. } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {
  22. scheduleDrain = function () {
  23. // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
  24. // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
  25. var scriptEl = global.document.createElement('script');
  26. scriptEl.onreadystatechange = function () {
  27. nextTick();
  28. scriptEl.onreadystatechange = null;
  29. scriptEl.parentNode.removeChild(scriptEl);
  30. scriptEl = null;
  31. };
  32. global.document.documentElement.appendChild(scriptEl);
  33. };
  34. } else {
  35. scheduleDrain = function () {
  36. setTimeout(nextTick, 0);
  37. };
  38. }
  39. } else {
  40. scheduleDrain = function () {
  41. process.nextTick(nextTick);
  42. };
  43. }
  44. var draining;
  45. var queue = [];
  46. //named nextTick for less confusing stack traces
  47. function nextTick() {
  48. draining = true;
  49. var i, oldQueue;
  50. var len = queue.length;
  51. while (len) {
  52. oldQueue = queue;
  53. queue = [];
  54. i = -1;
  55. while (++i < len) {
  56. oldQueue[i]();
  57. }
  58. len = queue.length;
  59. }
  60. draining = false;
  61. }
  62. module.exports = immediate;
  63. function immediate(task) {
  64. if (queue.push(task) === 1 && !draining) {
  65. scheduleDrain();
  66. }
  67. }