暫無描述

asap.js 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. var len = 0;
  2. var toString = {}.toString;
  3. var vertxNext;
  4. var customSchedulerFn;
  5. export var asap = function asap(callback, arg) {
  6. queue[len] = callback;
  7. queue[len + 1] = arg;
  8. len += 2;
  9. if (len === 2) {
  10. // If len is 2, that means that we need to schedule an async flush.
  11. // If additional callbacks are queued before the queue is flushed, they
  12. // will be processed by this flush that we are scheduling.
  13. if (customSchedulerFn) {
  14. customSchedulerFn(flush);
  15. } else {
  16. scheduleFlush();
  17. }
  18. }
  19. }
  20. export function setScheduler(scheduleFn) {
  21. customSchedulerFn = scheduleFn;
  22. }
  23. export function setAsap(asapFn) {
  24. asap = asapFn;
  25. }
  26. var browserWindow = (typeof window !== 'undefined') ? window : undefined;
  27. var browserGlobal = browserWindow || {};
  28. var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
  29. var isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
  30. // test for web worker but not in IE10
  31. var isWorker = typeof Uint8ClampedArray !== 'undefined' &&
  32. typeof importScripts !== 'undefined' &&
  33. typeof MessageChannel !== 'undefined';
  34. // node
  35. function useNextTick() {
  36. var nextTick = process.nextTick;
  37. // node version 0.10.x displays a deprecation warning when nextTick is used recursively
  38. // setImmediate should be used instead instead
  39. var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
  40. if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
  41. nextTick = setImmediate;
  42. }
  43. return function() {
  44. nextTick(flush);
  45. };
  46. }
  47. // vertx
  48. function useVertxTimer() {
  49. return function() {
  50. vertxNext(flush);
  51. };
  52. }
  53. function useMutationObserver() {
  54. var iterations = 0;
  55. var observer = new BrowserMutationObserver(flush);
  56. var node = document.createTextNode('');
  57. observer.observe(node, { characterData: true });
  58. return function() {
  59. node.data = (iterations = ++iterations % 2);
  60. };
  61. }
  62. // web worker
  63. function useMessageChannel() {
  64. var channel = new MessageChannel();
  65. channel.port1.onmessage = flush;
  66. return function () {
  67. channel.port2.postMessage(0);
  68. };
  69. }
  70. function useSetTimeout() {
  71. return function() {
  72. setTimeout(flush, 1);
  73. };
  74. }
  75. var queue = new Array(1000);
  76. function flush() {
  77. for (var i = 0; i < len; i+=2) {
  78. var callback = queue[i];
  79. var arg = queue[i+1];
  80. callback(arg);
  81. queue[i] = undefined;
  82. queue[i+1] = undefined;
  83. }
  84. len = 0;
  85. }
  86. function attemptVertex() {
  87. try {
  88. var r = require;
  89. var vertx = r('vertx');
  90. vertxNext = vertx.runOnLoop || vertx.runOnContext;
  91. return useVertxTimer();
  92. } catch(e) {
  93. return useSetTimeout();
  94. }
  95. }
  96. var scheduleFlush;
  97. // Decide what async method to use to triggering processing of queued callbacks:
  98. if (isNode) {
  99. scheduleFlush = useNextTick();
  100. } else if (BrowserMutationObserver) {
  101. scheduleFlush = useMutationObserver();
  102. } else if (isWorker) {
  103. scheduleFlush = useMessageChannel();
  104. } else if (browserWindow === undefined && typeof require === 'function') {
  105. scheduleFlush = attemptVertex();
  106. } else {
  107. scheduleFlush = useSetTimeout();
  108. }