Blame view

node_modules/next-tick/index.js 1.86 KB
aaac7fed   liuqimichale   add
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;
  }());