task.js 3.1 KB

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