task.js 3.3 KB

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