_microtask.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. // Promise.resolve without an argument throws an error in LG WebOS 2
  41. var promise = Promise.resolve(undefined);
  42. notify = function () {
  43. promise.then(flush);
  44. };
  45. // for other environments - macrotask based on:
  46. // - setImmediate
  47. // - MessageChannel
  48. // - window.postMessag
  49. // - onreadystatechange
  50. // - setTimeout
  51. } else {
  52. notify = function () {
  53. // strange IE + webpack dev server bug - use .call(global)
  54. macrotask.call(global, flush);
  55. };
  56. }
  57. return function (fn) {
  58. var task = { fn: fn, next: undefined };
  59. if (last) last.next = task;
  60. if (!head) {
  61. head = task;
  62. notify();
  63. } last = task;
  64. };
  65. };