Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/async/run.js
2868 views
1
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
goog.provide('goog.async.run');
16
17
goog.require('goog.async.WorkQueue');
18
goog.require('goog.async.nextTick');
19
goog.require('goog.async.throwException');
20
21
22
/**
23
* Fires the provided callback just before the current callstack unwinds, or as
24
* soon as possible after the current JS execution context.
25
* @param {function(this:THIS)} callback
26
* @param {THIS=} opt_context Object to use as the "this value" when calling
27
* the provided function.
28
* @template THIS
29
*/
30
goog.async.run = function(callback, opt_context) {
31
if (!goog.async.run.schedule_) {
32
goog.async.run.initializeRunner_();
33
}
34
if (!goog.async.run.workQueueScheduled_) {
35
// Nothing is currently scheduled, schedule it now.
36
goog.async.run.schedule_();
37
goog.async.run.workQueueScheduled_ = true;
38
}
39
40
goog.async.run.workQueue_.add(callback, opt_context);
41
};
42
43
44
/**
45
* Initializes the function to use to process the work queue.
46
* @private
47
*/
48
goog.async.run.initializeRunner_ = function() {
49
// If native Promises are available in the browser, just schedule the callback
50
// on a fulfilled promise, which is specified to be async, but as fast as
51
// possible. Use goog.global.Promise instead of just Promise because the
52
// relevant externs may be missing, and don't alias it because this could
53
// confuse the compiler into thinking the polyfill is required when it should
54
// be treated as optional.
55
if (String(goog.global.Promise).indexOf('[native code]') != -1) {
56
var promise = goog.global.Promise.resolve(undefined);
57
goog.async.run.schedule_ = function() {
58
promise.then(goog.async.run.processWorkQueue);
59
};
60
} else {
61
goog.async.run.schedule_ = function() {
62
goog.async.nextTick(goog.async.run.processWorkQueue);
63
};
64
}
65
};
66
67
68
/**
69
* Forces goog.async.run to use nextTick instead of Promise.
70
*
71
* This should only be done in unit tests. It's useful because MockClock
72
* replaces nextTick, but not the browser Promise implementation, so it allows
73
* Promise-based code to be tested with MockClock.
74
*
75
* However, we also want to run promises if the MockClock is no longer in
76
* control so we schedule a backup "setTimeout" to the unmocked timeout if
77
* provided.
78
*
79
* @param {function(function())=} opt_realSetTimeout
80
*/
81
goog.async.run.forceNextTick = function(opt_realSetTimeout) {
82
goog.async.run.schedule_ = function() {
83
goog.async.nextTick(goog.async.run.processWorkQueue);
84
if (opt_realSetTimeout) {
85
opt_realSetTimeout(goog.async.run.processWorkQueue);
86
}
87
};
88
};
89
90
91
/**
92
* The function used to schedule work asynchronousely.
93
* @private {function()}
94
*/
95
goog.async.run.schedule_;
96
97
98
/** @private {boolean} */
99
goog.async.run.workQueueScheduled_ = false;
100
101
102
/** @private {!goog.async.WorkQueue} */
103
goog.async.run.workQueue_ = new goog.async.WorkQueue();
104
105
106
if (goog.DEBUG) {
107
/**
108
* Reset the work queue. Only available for tests in debug mode.
109
*/
110
goog.async.run.resetQueue = function() {
111
goog.async.run.workQueueScheduled_ = false;
112
goog.async.run.workQueue_ = new goog.async.WorkQueue();
113
};
114
}
115
116
117
/**
118
* Run any pending goog.async.run work items. This function is not intended
119
* for general use, but for use by entry point handlers to run items ahead of
120
* goog.async.nextTick.
121
*/
122
goog.async.run.processWorkQueue = function() {
123
// NOTE: additional work queue items may be added while processing.
124
var item = null;
125
while (item = goog.async.run.workQueue_.remove()) {
126
try {
127
item.fn.call(item.scope);
128
} catch (e) {
129
goog.async.throwException(e);
130
}
131
goog.async.run.workQueue_.returnUnused(item);
132
}
133
134
// There are no more work items, allow processing to be scheduled again.
135
goog.async.run.workQueueScheduled_ = false;
136
};
137
138