-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathqueue.js
More file actions
146 lines (132 loc) · 3.71 KB
/
Copy pathqueue.js
File metadata and controls
146 lines (132 loc) · 3.71 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* # QUEUE
* Copyright(c) 2015 Stefano Balietti
* MIT Licensed
*
* Handles a simple queue of operations
*/
(function(JSUS) {
"use strict";
var QUEUE = {};
QUEUE.getQueue = function() {
return new Queue();
};
/**
* ## Queue constructor
*/
function Queue() {
/**
* ### Queue.queue
*
* The list of functions waiting to be executed.
*/
this.queue = [];
/**
* ### Queue.inProgress
*
* The list of operations ids currently in progress.
*/
this.inProgress = {};
}
/**
* ### Queue.isReady
*
* Returns TRUE if no operation is in progress
*
* @return {boolean} TRUE, if no operation is in progress
*/
Queue.prototype.isReady = function() {
return JSUS.isEmpty(this.inProgress);
};
/**
* ### Queue.onReady
*
* Executes the specified callback once the queue has been cleared
*
* Multiple functions to execute can be added, and they are executed
* sequentially once the queue is cleared.
*
* If the queue is already cleared, the function is executed immediately.
*
* @param {function} cb The callback to execute
*/
Queue.prototype.onReady = function(cb) {
if ('function' !== typeof cb) {
throw new TypeError('Queue.onReady: cb must be function. Found: ' +
cb);
}
if (JSUS.isEmpty(this.inProgress)) cb();
else this.queue.push(cb);
};
/**
* ### Queue.add
*
* Adds an item to the _inProgress_ index
*
* @param {string} key A tentative key name
*
* @return {string} The unique key to be used to unregister the operation
*/
Queue.prototype.add = function(key) {
if (key && 'string' !== typeof key) {
throw new Error('Queue.add: key must be string.');
}
key = JSUS.uniqueKey(this.inProgress, key);
if ('string' !== typeof key) {
throw new Error('Queue.add: an error occurred ' +
'generating unique key.');
}
this.inProgress[key] = key;
return key;
};
/**
* ### Queue.remove
*
* Remove a specified key from the _inProgress_ index
*
* @param {string} key The key to remove from the _inProgress_ index.
*/
Queue.prototype.remove = function(key) {
if ('string' !== typeof key) {
throw new Error('Queue.remove: key must be string.');
}
delete this.inProgress[key];
if (JSUS.isEmpty(this.inProgress)) {
this.executeAndClear();
}
};
/**
* ### Queue.getRemoveCb
*
* Returns a callback to remove an item from the _inProgress_ index
*
* This method is useful when the callbacks is defined inside loops,
* so that a closure is created around the variable key.
*
* @param {string} key The key to remove from the _inProgress_ index.
*
* @see Queue.remove
*/
Queue.prototype.getRemoveCb = function(key) {
var that;
if ('string' !== typeof key) {
throw new Error('Queue.getRemoveCb: key must be string.');
}
that = this;
return function() { that.remove(key); };
};
/**
* ### Queue.executeAndClear
*
* Executes sequentially all callbacks, and removes them from the queue
*/
Queue.prototype.executeAndClear = function() {
var i, len;
i = -1;
len = this.queue.length;
for ( ; ++i < len ; ) {
this.queue[i]();
}
};
JSUS.extend(QUEUE);
})('undefined' !== typeof JSUS ? JSUS : module.parent.exports.JSUS);