UNPKG

2.62 kBJavaScriptView Raw
1'use strict';
2var global = require('../internals/global');
3var safeGetBuiltIn = require('../internals/safe-get-built-in');
4var bind = require('../internals/function-bind-context');
5var macrotask = require('../internals/task').set;
6var Queue = require('../internals/queue');
7var IS_IOS = require('../internals/engine-is-ios');
8var IS_IOS_PEBBLE = require('../internals/engine-is-ios-pebble');
9var IS_WEBOS_WEBKIT = require('../internals/engine-is-webos-webkit');
10var IS_NODE = require('../internals/engine-is-node');
11
12var MutationObserver = global.MutationObserver || global.WebKitMutationObserver;
13var document = global.document;
14var process = global.process;
15var Promise = global.Promise;
16var microtask = safeGetBuiltIn('queueMicrotask');
17var notify, toggle, node, promise, then;
18
19// modern engines have queueMicrotask method
20if (!microtask) {
21 var queue = new Queue();
22
23 var flush = function () {
24 var parent, fn;
25 if (IS_NODE && (parent = process.domain)) parent.exit();
26 while (fn = queue.get()) try {
27 fn();
28 } catch (error) {
29 if (queue.head) notify();
30 throw error;
31 }
32 if (parent) parent.enter();
33 };
34
35 // browsers with MutationObserver, except iOS - https://github.com/zloirock/core-js/issues/339
36 // also except WebOS Webkit https://github.com/zloirock/core-js/issues/898
37 if (!IS_IOS && !IS_NODE && !IS_WEBOS_WEBKIT && MutationObserver && document) {
38 toggle = true;
39 node = document.createTextNode('');
40 new MutationObserver(flush).observe(node, { characterData: true });
41 notify = function () {
42 node.data = toggle = !toggle;
43 };
44 // environments with maybe non-completely correct, but existent Promise
45 } else if (!IS_IOS_PEBBLE && Promise && Promise.resolve) {
46 // Promise.resolve without an argument throws an error in LG WebOS 2
47 promise = Promise.resolve(undefined);
48 // workaround of WebKit ~ iOS Safari 10.1 bug
49 promise.constructor = Promise;
50 then = bind(promise.then, promise);
51 notify = function () {
52 then(flush);
53 };
54 // Node.js without promises
55 } else if (IS_NODE) {
56 notify = function () {
57 process.nextTick(flush);
58 };
59 // for other environments - macrotask based on:
60 // - setImmediate
61 // - MessageChannel
62 // - window.postMessage
63 // - onreadystatechange
64 // - setTimeout
65 } else {
66 // `webpack` dev server bug on IE global methods - use bind(fn, global)
67 macrotask = bind(macrotask, global);
68 notify = function () {
69 macrotask(flush);
70 };
71 }
72
73 microtask = function (fn) {
74 if (!queue.head) notify();
75 queue.add(fn);
76 };
77}
78
79module.exports = microtask;