_microtask.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. var global = require('./_global');
  2. var macrotask = require('./_task').set;
  3. var Observer = global.MutationObserver || global.WebKitMutationObserver;
  4. var process = global.process;
  5. var Promise = global.Promise;
  6. var isNode = require('./_cof')(process) == 'process';
  7. module.exports = function () {
  8. var head, last, notify;
  9. var flush = function () {
  10. var parent, fn;
  11. if (isNode && (parent = process.domain)) parent.exit();
  12. while (head) {
  13. fn = head.fn;
  14. head = head.next;
  15. try {
  16. fn();
  17. } catch (e) {
  18. if (head) notify();
  19. else last = undefined;
  20. throw e;
  21. }
  22. } last = undefined;
  23. if (parent) parent.enter();
  24. };
  25. // Node.js
  26. if (isNode) {
  27. notify = function () {
  28. process.nextTick(flush);
  29. };
  30. // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339
  31. } else if (Observer && !(global.navigator && global.navigator.standalone)) {
  32. var toggle = true;
  33. var node = document.createTextNode('');
  34. new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
  35. notify = function () {
  36. node.data = toggle = !toggle;
  37. };
  38. // environments with maybe non-completely correct, but existent Promise
  39. } else if (Promise && Promise.resolve) {
  40. var promise = Promise.resolve();
  41. notify = function () {
  42. promise.then(flush);
  43. };
  44. // for other environments - macrotask based on:
  45. // - setImmediate
  46. // - MessageChannel
  47. // - window.postMessag
  48. // - onreadystatechange
  49. // - setTimeout
  50. } else {
  51. notify = function () {
  52. // strange IE + webpack dev server bug - use .call(global)
  53. macrotask.call(global, flush);
  54. };
  55. }
  56. return function (fn) {
  57. var task = { fn: fn, next: undefined };
  58. if (last) last.next = task;
  59. if (!head) {
  60. head = task;
  61. notify();
  62. } last = task;
  63. };
  64. };