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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/* <copyright>
This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
</copyright> */
/**
Defines [nextTick()]{#link nextTick}
@see nextTick
@module montage/core/next-tick
*/
/**
@function
@name nextTick
*/
(function (definition) {
if (typeof bootstrap !== "undefined") {
bootstrap("core/next-tick", definition);
} else if (typeof require !== "undefined") {
definition(require, exports, module);
} else {
definition({}, {}, {});
}
})(function (require, exports, module) {
var nextTick;
// Node implementation:
if (typeof process !== "undefined") {
nextTick = process.nextTick;
// Browser implementation: based on MessageChannel, setImmediate, or setTimeout
} else {
// queue of tasks implemented as a singly linked list with a head node
var head = {}, tail = head;
// whether a task is pending is represented by the existence of head.next
nextTick = function (task) {
var alreadyPending = head.next;
tail = tail.next = {task: task};
if (!alreadyPending) {
// setImmediate,
// postMessage, or
// setTimeout:
request(flush, 0);
}
}
var flush = function () {
try {
// unroll all pending events
while (head.next) {
head = head.next;
// guarantee consistent queue state
// before task, because it may throw
head.task(); // may throw
}
} finally {
// if a task throws an exception and
// there are more pending tasks, dispatch
// another event
if (head.next) {
// setImmediate,
// postMessage, or
// setTimeout:
request(flush, 0);
}
}
};
var request; // must always be called like request(flush, 0);
// in order of desirability:
if (typeof setImmediate !== "undefined") {
request = setImmediate;
} else if (typeof MessageChannel !== "undefined") {
// http://www.nonblocking.io/2011/06/windownexttick.html
var channel = new MessageChannel();
channel.port1.onmessage = flush;
request = function (flush, zero) {
channel.port2.postMessage(0);
};
} else {
request = setTimeout;
}
}
exports.nextTick = nextTick;
});
|