Comparing version 0.1.0 to 0.2.0
78
index.js
@@ -10,3 +10,3 @@ var slice = [].slice | ||
this.length = 0 | ||
this.pending = 0 | ||
this.errors = [] | ||
@@ -16,35 +16,58 @@ this.values = [] | ||
// to make .shift() a yieldable | ||
this.next = function (done) { | ||
self.queue.push(done) | ||
} | ||
// passed to async functions | ||
// private! | ||
this.callback = function (err, res) { | ||
self.length-- | ||
self.pending-- | ||
if (!err && arguments.length > 2) | ||
res = slice.call(arguments) | ||
if (self.queue.length) | ||
self.queue.shift()(err, res) | ||
else if (err) | ||
self.errors.push(err) | ||
else | ||
self.values.push(res) | ||
if (arguments.length > 2) | ||
res = slice.call(arguments, 1) | ||
self.push(err || res) | ||
} | ||
} | ||
this.next = function (done) { | ||
self.queue.push(done) | ||
Channel.prototype = { | ||
get length() { | ||
return this.pending | ||
+ this.values.length | ||
+ this.queue.length | ||
} | ||
} | ||
Channel.prototype._push = function (err, res) { | ||
if (this.queue.length) | ||
this.queue.shift()(err, res) | ||
else if (err) | ||
this.errors.push(err) | ||
else | ||
this.values.push(res) | ||
} | ||
// .push(err) | ||
// .push(val) | ||
// .push(val...) | ||
Channel.prototype.unshift = | ||
Channel.prototype.push = function (val) { | ||
var self = this | ||
// push values | ||
if (arguments.length) { | ||
if (val instanceof Error) | ||
return this._push(val) | ||
if (arguments.length > 1) | ||
val = slice.call(arguments) | ||
return this._push(null, val) | ||
} | ||
this.length++ | ||
// push a value | ||
if (arguments.length > 1) | ||
val = slice.call(arguments) | ||
if (val) | ||
return this.callback(null, val) | ||
// return a callback | ||
this.pending++ | ||
return this.callback | ||
} | ||
// var val = yield* shift() | ||
Channel.prototype.pop = | ||
Channel.prototype.read = | ||
Channel.prototype.shift = function* () { | ||
@@ -57,7 +80,10 @@ // throw the first error | ||
return this.values.shift() | ||
// no more pending callbacks, return falsey | ||
if (!this.length) | ||
return | ||
// wait for the next callback | ||
return yield this.next | ||
// if pending callbacks, queue | ||
if (this.pending) | ||
return yield this.next | ||
} | ||
Channel.prototype.end = function* () { | ||
while (this.length) | ||
yield* this.shift() | ||
} |
{ | ||
"name": "archan", | ||
"description": "Array-like generator-based channels", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "Jonathan Ong", |
@@ -54,2 +54,3 @@ # Archan [![Build Status](https://travis-ci.org/cojs/archan.png)](https://travis-ci.org/cojs/archan) | ||
ch.push(1, 2, 3) // adds [1, 2, 3] | ||
ch.push(new Error()) // adds an error, will be thrown on next .shift() | ||
``` | ||
@@ -64,5 +65,28 @@ | ||
### var val = yield* ch.read() | ||
An alias for `ch.shift()`. | ||
This alias demonstrates archan's synonymity with [Readable Streams](http://nodejs.org/api/stream.html#stream_class_stream_readable) in object mode: | ||
```js | ||
var stream = archan() | ||
stream.push('first') | ||
stream.push('second') | ||
stream.push('third') | ||
stream.push(null) | ||
assert.equal('first', yield stream.read()) | ||
assert.equal('second', yield stream.read()) | ||
assert.equal('third', yield stream.read()) | ||
assert.equal(null, yield stream.read()) | ||
``` | ||
Note that unlike node's streams, | ||
order is not preserved, | ||
specifically with asynchronous functions. | ||
### ch.length | ||
The number of pending callbacks. | ||
The number of values in the channel, | ||
both pending and ready. | ||
Note that if you ever return a `falsey` value in any of your callbacks, | ||
@@ -89,2 +113,14 @@ the while loop in the example will not work as expected. | ||
### yield* ch.end() | ||
Wait for all the values to be `yield`ed. | ||
Useful if you don't need the resulting values and are using `archan` just for control flow. | ||
Basically does this: | ||
```js | ||
while (ch.length) { | ||
yield* ch.shift() | ||
} | ||
``` | ||
## License | ||
@@ -91,0 +127,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6395
72
145