-
Notifications
You must be signed in to change notification settings - Fork 110
/
Copy pathpromise-queue.js
71 lines (58 loc) · 2.46 KB
/
promise-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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// A promise queue is an asynchronous linked list, representing a sequence of
// values over time.
// Consuming and producing that sequence are temporaly independent.
// For each respective promise and resolution, the promise may be gotten first
// and put later, or put first and gotten later.
// This implementation comes from Mark Miller's [Concurrency Strawman][] for
// ECMAScript.
//
// [Concurrency Strawman]: http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
"use strict";
var Promise = require("./promise");
// ## PromiseQueue
// The promise queue constructor returns an entangled `get` and `put` pair.
// These methods may be passed as functions, granting either the capability to
// give or take but not necessarily both.
// Internally, a promise queue is an asynchronous linked list of deferreds.
// The `ends` variable is a `promise` and `resolver` pair.
// The `promise` is a promise for the next `ends` pair after this promise is
// taken.
// The `resolver` advances the `ends` pair after a resolution is given.
// The `promise` and `resolver` are independent properties, not necessarily
// corresponding to the same deferred.
module.exports = PromiseQueue;
function PromiseQueue(values) {
if (!(this instanceof PromiseQueue)) {
return new PromiseQueue();
}
var self = this;
var ends = Promise.defer();
// The `resolver` side of a promise queue adds a `{head, tail}` node to the
// asynchronous linked list.
// The `put` method creates a new link to the resolver side with the given
// `head` value, and advances the `resolver` side of the list.
this.put = function (value) {
var next = Promise.defer();
ends.resolver.return({
head: value,
tail: next.promise
});
ends.resolver = next.resolver;
};
// The `promise` end of a promise queue is a promise for a `{head, tail}`
// pair.
// The `head` will be the next value, and the `tail` will be a promise for
// the remaining nodes of the list.
// The `get` method obtains and returns a promise for the `head` value and
// advances the `promise` to become the `tail`.
this.get = function () {
var result = ends.promise.get("head");
ends.promise = ends.promise.get("tail");
return result;
};
// The promise queue constructor allows the queue to be initialized with
// a given population of values.
if (values) {
values.forEach(this.put, this);
}
}