aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/core/next-tick.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/core/next-tick.js')
-rw-r--r--node_modules/montage/core/next-tick.js91
1 files changed, 91 insertions, 0 deletions
diff --git a/node_modules/montage/core/next-tick.js b/node_modules/montage/core/next-tick.js
new file mode 100644
index 00000000..0c3e209a
--- /dev/null
+++ b/node_modules/montage/core/next-tick.js
@@ -0,0 +1,91 @@
1/* <copyright>
2 This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3 No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4 (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5 </copyright> */
6
7/**
8 Defines [nextTick()]{#link nextTick}
9 @see nextTick
10 @module montage/core/next-tick
11*/
12
13/**
14 @function
15 @name nextTick
16*/
17
18(function (definition) {
19 if (typeof bootstrap !== "undefined") {
20 bootstrap("core/next-tick", definition);
21 } else if (typeof require !== "undefined") {
22 definition(require, exports, module);
23 } else {
24 definition({}, {}, {});
25 }
26})(function (require, exports, module) {
27
28var nextTick;
29// Node implementation:
30if (typeof process !== "undefined") {
31 nextTick = process.nextTick;
32// Browser implementation: based on MessageChannel, setImmediate, or setTimeout
33} else {
34
35 // queue of tasks implemented as a singly linked list with a head node
36 var head = {}, tail = head;
37 // whether a task is pending is represented by the existence of head.next
38
39 nextTick = function (task) {
40 var alreadyPending = head.next;
41 tail = tail.next = {task: task};
42 if (!alreadyPending) {
43 // setImmediate,
44 // postMessage, or
45 // setTimeout:
46 request(flush, 0);
47 }
48 }
49
50 var flush = function () {
51 try {
52 // unroll all pending events
53 while (head.next) {
54 head = head.next;
55 // guarantee consistent queue state
56 // before task, because it may throw
57 head.task(); // may throw
58 }
59 } finally {
60 // if a task throws an exception and
61 // there are more pending tasks, dispatch
62 // another event
63 if (head.next) {
64 // setImmediate,
65 // postMessage, or
66 // setTimeout:
67 request(flush, 0);
68 }
69 }
70 };
71
72 var request; // must always be called like request(flush, 0);
73 // in order of desirability:
74 if (typeof setImmediate !== "undefined") {
75 request = setImmediate;
76 } else if (typeof MessageChannel !== "undefined") {
77 // http://www.nonblocking.io/2011/06/windownexttick.html
78 var channel = new MessageChannel();
79 channel.port1.onmessage = flush;
80 request = function (flush, zero) {
81 channel.port2.postMessage(0);
82 };
83 } else {
84 request = setTimeout;
85 }
86
87}
88
89exports.nextTick = nextTick;
90
91});