heyujie
2021-05-20 6ebdefb4a5b2be82a8c452c0bb4624f3d85a17b7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'use strict';
 
var callable, byObserver;
 
callable = function (fn) {
    if (typeof fn !== 'function') throw new TypeError(fn + " is not a function");
    return fn;
};
 
byObserver = function (Observer) {
    var node = document.createTextNode(''), queue, currentQueue, i = 0;
    new Observer(function () {
        var callback;
        if (!queue) {
            if (!currentQueue) return;
            queue = currentQueue;
        } else if (currentQueue) {
            queue = currentQueue.concat(queue);
        }
        currentQueue = queue;
        queue = null;
        if (typeof currentQueue === 'function') {
            callback = currentQueue;
            currentQueue = null;
            callback();
            return;
        }
        node.data = (i = ++i % 2); // Invoke other batch, to handle leftover callbacks in case of crash
        while (currentQueue) {
            callback = currentQueue.shift();
            if (!currentQueue.length) currentQueue = null;
            callback();
        }
    }).observe(node, { characterData: true });
    return function (fn) {
        callable(fn);
        if (queue) {
            if (typeof queue === 'function') queue = [queue, fn];
            else queue.push(fn);
            return;
        }
        queue = fn;
        node.data = (i = ++i % 2);
    };
};
 
module.exports = (function () {
    // Node.js
    if ((typeof process === 'object') && process && (typeof process.nextTick === 'function')) {
        return process.nextTick;
    }
 
    // MutationObserver
    if ((typeof document === 'object') && document) {
        if (typeof MutationObserver === 'function') return byObserver(MutationObserver);
        if (typeof WebKitMutationObserver === 'function') return byObserver(WebKitMutationObserver);
    }
 
    // W3C Draft
    // http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
    if (typeof setImmediate === 'function') {
        return function (cb) { setImmediate(callable(cb)); };
    }
 
    // Wide available standard
    if ((typeof setTimeout === 'function') || (typeof setTimeout === 'object')) {
        return function (cb) { setTimeout(callable(cb), 0); };
    }
 
    return null;
}());