task.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. var global = require('../internals/global');
  2. var fails = require('../internals/fails');
  3. var bind = require('../internals/function-bind-context');
  4. var html = require('../internals/html');
  5. var createElement = require('../internals/document-create-element');
  6. var IS_IOS = require('../internals/engine-is-ios');
  7. var IS_NODE = require('../internals/engine-is-node');
  8. var set = global.setImmediate;
  9. var clear = global.clearImmediate;
  10. var process = global.process;
  11. var MessageChannel = global.MessageChannel;
  12. var Dispatch = global.Dispatch;
  13. var counter = 0;
  14. var queue = {};
  15. var ONREADYSTATECHANGE = 'onreadystatechange';
  16. var location, defer, channel, port;
  17. try {
  18. // Deno throws a ReferenceError on `location` access without `--location` flag
  19. location = global.location;
  20. } catch (error) { /* empty */ }
  21. var run = function (id) {
  22. // eslint-disable-next-line no-prototype-builtins -- safe
  23. if (queue.hasOwnProperty(id)) {
  24. var fn = queue[id];
  25. delete queue[id];
  26. fn();
  27. }
  28. };
  29. var runner = function (id) {
  30. return function () {
  31. run(id);
  32. };
  33. };
  34. var listener = function (event) {
  35. run(event.data);
  36. };
  37. var post = function (id) {
  38. // old engines have not location.origin
  39. global.postMessage(String(id), location.protocol + '//' + location.host);
  40. };
  41. // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
  42. if (!set || !clear) {
  43. set = function setImmediate(fn) {
  44. var args = [];
  45. var argumentsLength = arguments.length;
  46. var i = 1;
  47. while (argumentsLength > i) args.push(arguments[i++]);
  48. queue[++counter] = function () {
  49. // eslint-disable-next-line no-new-func -- spec requirement
  50. (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
  51. };
  52. defer(counter);
  53. return counter;
  54. };
  55. clear = function clearImmediate(id) {
  56. delete queue[id];
  57. };
  58. // Node.js 0.8-
  59. if (IS_NODE) {
  60. defer = function (id) {
  61. process.nextTick(runner(id));
  62. };
  63. // Sphere (JS game engine) Dispatch API
  64. } else if (Dispatch && Dispatch.now) {
  65. defer = function (id) {
  66. Dispatch.now(runner(id));
  67. };
  68. // Browsers with MessageChannel, includes WebWorkers
  69. // except iOS - https://github.com/zloirock/core-js/issues/624
  70. } else if (MessageChannel && !IS_IOS) {
  71. channel = new MessageChannel();
  72. port = channel.port2;
  73. channel.port1.onmessage = listener;
  74. defer = bind(port.postMessage, port, 1);
  75. // Browsers with postMessage, skip WebWorkers
  76. // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
  77. } else if (
  78. global.addEventListener &&
  79. typeof postMessage == 'function' &&
  80. !global.importScripts &&
  81. location && location.protocol !== 'file:' &&
  82. !fails(post)
  83. ) {
  84. defer = post;
  85. global.addEventListener('message', listener, false);
  86. // IE8-
  87. } else if (ONREADYSTATECHANGE in createElement('script')) {
  88. defer = function (id) {
  89. html.appendChild(createElement('script'))[ONREADYSTATECHANGE] = function () {
  90. html.removeChild(this);
  91. run(id);
  92. };
  93. };
  94. // Rest old browsers
  95. } else {
  96. defer = function (id) {
  97. setTimeout(runner(id), 0);
  98. };
  99. }
  100. }
  101. module.exports = {
  102. set: set,
  103. clear: clear
  104. };