forked from jamesshore/lets_code_javascript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpriorityQueue.js
More file actions
113 lines (90 loc) · 3.45 KB
/
priorityQueue.js
File metadata and controls
113 lines (90 loc) · 3.45 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
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (worker, concurrency) {
function _compareTasks(a, b) {
return a.priority - b.priority;
}
function _binarySearch(sequence, item, compare) {
var beg = -1,
end = sequence.length - 1;
while (beg < end) {
var mid = beg + (end - beg + 1 >>> 1);
if (compare(item, sequence[mid]) >= 0) {
beg = mid;
} else {
end = mid - 1;
}
}
return beg;
}
function _insert(q, data, priority, callback) {
if (callback != null && typeof callback !== 'function') {
throw new Error('task callback must be a function');
}
q.started = true;
if (!(0, _isArray2.default)(data)) {
data = [data];
}
if (data.length === 0) {
// call drain immediately if there are no tasks
return (0, _setImmediate2.default)(function () {
q.drain();
});
}
(0, _arrayEach2.default)(data, function (task) {
var item = {
data: task,
priority: priority,
callback: typeof callback === 'function' ? callback : _noop2.default
};
q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
(0, _setImmediate2.default)(q.process);
});
}
// Start with a normal queue
var q = (0, _queue2.default)(worker, concurrency);
// Override push to accept second parameter representing priority
q.push = function (data, priority, callback) {
_insert(q, data, priority, callback);
};
// Remove unshift function
delete q.unshift;
return q;
};
var _arrayEach = require('lodash/_arrayEach');
var _arrayEach2 = _interopRequireDefault(_arrayEach);
var _isArray = require('lodash/isArray');
var _isArray2 = _interopRequireDefault(_isArray);
var _noop = require('lodash/noop');
var _noop2 = _interopRequireDefault(_noop);
var _setImmediate = require('./setImmediate');
var _setImmediate2 = _interopRequireDefault(_setImmediate);
var _queue = require('./queue');
var _queue2 = _interopRequireDefault(_queue);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
module.exports = exports['default'];
/**
* The same as {@link async.queue} only tasks are assigned a priority and
* completed in ascending priority order.
*
* @name priorityQueue
* @static
* @memberOf async
* @see async.queue
* @category Control Flow
* @param {Function} worker - An asynchronous function for processing a queued
* task, which must call its `callback(err)` argument when finished, with an
* optional `error` as an argument. If you want to handle errors from an
* individual task, pass a callback to `q.push()`. Invoked with
* (task, callback).
* @param {number} concurrency - An `integer` for determining how many `worker`
* functions should be run in parallel. If omitted, the concurrency defaults to
* `1`. If the concurrency is `0`, an error is thrown.
* @returns {queue} A priorityQueue object to manage the tasks. There are two
* differences between `queue` and `priorityQueue` objects:
* * `push(task, priority, [callback])` - `priority` should be a number. If an
* array of `tasks` is given, all tasks will be assigned the same priority.
* * The `unshift` method was removed.
*/