iter-tools-es
Version:
The iterable toolbox
103 lines (86 loc) • 1.55 kB
JavaScript
const {
IterableIterator
} = require('./iterable-iterator.js');
const {
callReturn
} = require('./iterable.js');
class QueueItem {
constructor(step) {
this.step = step;
this.next = null;
}
}
class Fork extends IterableIterator {
constructor(head, exchange) {
super();
this.head = head;
this.done = false;
this.exchange = exchange;
}
next() {
const {
done,
exchange
} = this;
if (done) {
return {
value: undefined,
done
};
} else {
let {
head
} = this;
if (!head.next) exchange.fetch();
head = head.next;
const {
step
} = head;
this.done = step.done;
this.head = head;
return step;
}
}
return() {
const {
done,
exchange
} = this;
if (!done) exchange.return();
return {
value: undefined,
done: true
};
}
}
class Exchange {
constructor(iterator) {
this.iterator = iterator;
this.tail = new QueueItem(null);
this.head = this.tail;
this.forks = 0;
}
fork() {
++this.forks;
return new Fork(this.tail, this);
}
advance() {
this.tail = this.tail.next;
}
fetch() {
const step = this.iterator.next();
const newItem = new QueueItem(step);
this.head.next = this.head = newItem;
}
return() {
--this.forks;
if (this.forks === 0) {
callReturn(this.iterator);
}
return {
value: undefined,
done: true
};
}
}
exports.Exchange = Exchange;