forked from medikoo/deferred
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdynamic-queue.js
53 lines (47 loc) · 1.43 KB
/
dynamic-queue.js
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
// Dynamic queue handler
// Allows to create a promise queue, where new promises can be added to queue until last promise in
// a queue resolves. Queue promise resolves with `undefined` value, when last promises resolves.
'use strict';
var aFrom = require('es5-ext/array/from')
, ensureIterable = require('es5-ext/iterable/validate-object')
, assign = require('es5-ext/object/assign')
, deferred = require('./deferred')
, isPromise = require('./is-promise')
, assimilate = require('./assimilate')
, DynamicQueue;
module.exports = DynamicQueue = function (list) {
if (!(this instanceof DynamicQueue)) return new DynamicQueue(list);
list = aFrom(ensureIterable(list));
assign(this, deferred());
list.every(this.add, this);
if (!this.waiting) {
this.resolve();
return;
}
this.initialized = true;
};
DynamicQueue.prototype = {
waiting: 0,
initialized: false,
add: function (value) {
if (this.promise.resolved) throw new Error("Queue was already resolved");
++this.waiting;
value = assimilate(value);
if (isPromise(value)) {
if (!value.resolved) {
value.done(this._processValue.bind(this), this.reject);
return true;
}
if (value.failed) {
this.reject(value.value);
return false;
}
}
return this._processValue();
},
_processValue: function () {
if (this.promise.resolved) return;
if (!--this.waiting && this.initialized) this.resolve();
return true;
}
};