Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/third_party/closure/goog/async/run.js
4096 views
1
/**
2
* @license
3
* Copyright The Closure Library Authors.
4
* SPDX-License-Identifier: Apache-2.0
5
*/
6
goog.module('goog.async.run');
7
goog.module.declareLegacyNamespace();
8
9
const WorkQueue = goog.require('goog.async.WorkQueue');
10
const asyncStackTag = goog.require('goog.debug.asyncStackTag');
11
const nextTick = goog.require('goog.async.nextTick');
12
const throwException = goog.require('goog.async.throwException');
13
14
/**
15
* @define {boolean} If true, use the global Promise to implement run
16
* assuming either the native, or polyfill version will be used. Does still
17
* permit tests to use forceNextTick.
18
*/
19
goog.ASSUME_NATIVE_PROMISE = goog.define('goog.ASSUME_NATIVE_PROMISE', false);
20
21
/**
22
* The function used to schedule work asynchronousely.
23
* @private {function()}
24
*/
25
let schedule;
26
27
/** @private {boolean} */
28
let workQueueScheduled = false;
29
30
/** @type {!WorkQueue} */
31
let workQueue = new WorkQueue();
32
33
/**
34
* Fires the provided callback just before the current callstack unwinds, or as
35
* soon as possible after the current JS execution context.
36
* @param {function(this:THIS)} callback
37
* @param {THIS=} context Object to use as the "this value" when calling the
38
* provided function.
39
* @template THIS
40
*/
41
let run = (callback, context = undefined) => {
42
if (!schedule) {
43
initializeRunner();
44
}
45
if (!workQueueScheduled) {
46
// Nothing is currently scheduled, schedule it now.
47
schedule();
48
workQueueScheduled = true;
49
}
50
callback = asyncStackTag.wrap(callback, 'goog.async.run');
51
52
workQueue.add(callback, context);
53
};
54
55
/** Initializes the function to use to process the work queue. */
56
let initializeRunner = () => {
57
if (goog.ASSUME_NATIVE_PROMISE ||
58
(goog.global.Promise && goog.global.Promise.resolve)) {
59
// Use goog.global.Promise instead of just Promise because the relevant
60
// externs may be missing, and don't alias it because this could confuse the
61
// compiler into thinking the polyfill is required when it should be treated
62
// as optional.
63
const promise = goog.global.Promise.resolve(undefined);
64
schedule = () => {
65
promise.then(run.processWorkQueue);
66
};
67
} else {
68
schedule = () => {
69
nextTick(run.processWorkQueue);
70
};
71
}
72
};
73
74
/**
75
* Forces run to use nextTick instead of Promise.
76
* This should only be done in unit tests. It's useful because MockClock
77
* replaces nextTick, but not the browser Promise implementation, so it allows
78
* Promise-based code to be tested with MockClock.
79
* However, we also want to run promises if the MockClock is no longer in
80
* control so we schedule a backup "setTimeout" to the unmocked timeout if
81
* provided.
82
* @param {function(function())=} realSetTimeout
83
*/
84
run.forceNextTick = (realSetTimeout = undefined) => {
85
schedule = () => {
86
nextTick(run.processWorkQueue);
87
if (realSetTimeout) {
88
realSetTimeout(run.processWorkQueue);
89
}
90
};
91
};
92
93
if (goog.DEBUG) {
94
/** Reset the work queue. Only available for tests in debug mode. */
95
run.resetQueue = () => {
96
workQueueScheduled = false;
97
workQueue = new WorkQueue();
98
};
99
100
/** Resets the scheduler. Only available for tests in debug mode. */
101
run.resetSchedulerForTest = () => {
102
initializeRunner();
103
};
104
}
105
106
/**
107
* Run any pending run work items. This function is not intended
108
* for general use, but for use by entry point handlers to run items ahead of
109
* nextTick.
110
*/
111
run.processWorkQueue = () => {
112
// NOTE: additional work queue items may be added while processing.
113
let item = null;
114
while (item = workQueue.remove()) {
115
try {
116
item.fn.call(item.scope);
117
} catch (e) {
118
throwException(e);
119
}
120
workQueue.returnUnused(item);
121
}
122
123
// There are no more work items, allow processing to be scheduled again.
124
workQueueScheduled = false;
125
};
126
127
exports = run;
128
129