Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

To promise #17

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
language: node_js
node_js:
- "0.11"
- "0.12"
- "4"
- "5"
29 changes: 13 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Chan

A [golang](http://golang.org) like channel implementation for JavaScript that
works well with [co](https://github.com/visionmedia/co).
works well with `ES7 async & await` and [co](https://github.com/tj/co)..

[![Build Status](https://travis-ci.org/brentburg/chan.png)](https://travis-ci.org/brentburg/chan)
[![Code Climate](https://codeclimate.com/github/brentburgoyne/chan.png)](https://codeclimate.com/github/brentburgoyne/chan)
Expand All @@ -14,6 +14,7 @@ works well with [co](https://github.com/visionmedia/co).
- Channels can be closed
- API designed to work well with generators and co
- Can be used without generators
- API designed to work well with async&await
- Channels can be selected similar to Go's select statement

## Installation
Expand All @@ -37,30 +38,26 @@ typeof ch // -> 'function'
### Sending values to the channel

Values are added to the
channel by calling the function with either `(value)` or `(error, value)`. The
return value is a thunk (a function that take a node-style callback as its only
argument). The callback given to the thunk is called once the value is added.
channel by calling the function with either `(value)` or `(error, value)`.
The return value is a Promise.

```js
ch('foo')(function (err) {
if (err) {
// There was an error putting the value on the channel
} else {
// The value was successfully put on the channel
}
ch('foo').then(function () {
// The value was successfully put on the channel
}).catch(function (err) {
// There was an error putting the value on the channel
})
```

### Receiving values from the channel

Values are removed from the channel by calling it with a node-style callback as
this first argument. When a value is available on the channel the callback is
called with the value or error. In this case the channel itself can also be a
thunk.
Values are taken off the channel by resolving the channel promise repeatedly.

```js
ch(function (err, val) {
// called when there is a value or error on the channel
ch.then(function (val) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be implemented. The channel is a function does not have a then method.

// called when there is a value on the channel
}).catch(function (err) {
// called when there is an error on the channel
})
```

Expand Down
4 changes: 2 additions & 2 deletions examples/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ co(function *() {
console.log('Response added to channel for: ' + urls[i])
}
ch.close()
})()
})

co(function *() {
while (!ch.done()) {
yield ch
yield chan.timeout(1000)
console.log('Channel yielded')
}
})()
})
4 changes: 2 additions & 2 deletions examples/buffered.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ co(function *() {
yield chan.timeout(100)
console.log('<-- ' + (yield ch))
}
})()
})


co(function *() {
Expand All @@ -20,4 +20,4 @@ co(function *() {
console.log(n + ' -->')
}
ch.close()
})()
})
4 changes: 2 additions & 2 deletions examples/close.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ co(function *() {
}
}
console.log('Done!')
})()
})

co(function *() {
var n = 10
Expand All @@ -30,4 +30,4 @@ co(function *() {
ch.close()
}
}
})()
})
4 changes: 2 additions & 2 deletions examples/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ var fs = require('fs')
co(function *() {
var ch = chan()

fs.readFile('something', ch)
fs.readFile(__filename, ch)

try {
yield ch
} catch (err) {
console.log('failed: %s', err.message)
}
})()
})
4 changes: 2 additions & 2 deletions examples/interval.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ co(function *() {
while (true) {
console.log('a: ' + (yield int))
}
})()
})

co(function *() {
var int = chan.interval(30)
while (true) {
console.log('b: ' + (yield int))
}
})()
})
4 changes: 2 additions & 2 deletions examples/passing.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ co(function *() {
while ((n = yield ch)) {
console.log(n)
}
})()
})

co(function *() {
var n = 50
Expand All @@ -19,4 +19,4 @@ co(function *() {
yield chan.timeout(100)
ch(n)
}
})()
})
2 changes: 1 addition & 1 deletion examples/requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ co(function *() {
while ((res = yield ch)) {
console.log(res.status)
}
})()
})
2 changes: 1 addition & 1 deletion examples/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ co(function *() {
}
}

})()
})
2 changes: 1 addition & 1 deletion examples/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ co(function *() {
}

console.log('Stream ended')
})()
})
4 changes: 2 additions & 2 deletions examples/timeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ var co = require('co')
co(function *() {
var ch = chan()
request.get('http://google.com', ch)

switch (yield chan.select(ch, chan.timeout(1000))) {
case ch:
console.log('Google loaded.')
break
default:
console.log('Timeout of 1 second reached.')
}
})()
})
18 changes: 13 additions & 5 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,22 @@ function async(ch, fn/*, args...*/) {
if (arguments.length > 2) {
val = [].slice.call(arguments, 1)
}
ch(err, val)(function (err) {
receiver[err ? 'error' : 'add'](err)
ch(err, val).then(function (val) {
receiver.add(val)
}).catch(function (err) {
receiver.error(err)
})
})

fn.apply(context, args)

return function (cb) {
receiver.callback(cb)
}
return new Promise(function (resolve, reject) {
receiver.callback(function (err, val) {
if (err) {
reject(err)
} else {
resolve(val)
}
})
})
}
14 changes: 10 additions & 4 deletions lib/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Channel.lastCalled = null
* @param {Function} cb
* @api private
*/
Channel.prototype.get = function (cb){
Channel.prototype.get = function (cb) {
if (this.done()) {
this.callEmpty(cb)
} else if (this.items.length > 0 || this.pendingAdds.length > 0) {
Expand Down Expand Up @@ -96,9 +96,15 @@ Channel.prototype.add = function (val){
this.pendingAdds.push(receiver)
}

return function (cb) {
receiver.callback(cb)
}
return new Promise(function (resolve, reject) {
receiver.callback(function (err, val) {
if (err) {
reject(err)
} else {
resolve(val)
}
})
})
}

/**
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@
},
"homepage": "https://github.com/brentburgoyne/chan",
"devDependencies": {
"co": "^3.0.6",
"co": "^4.6.0",
"expect.js": "^0.3.1",
"mocha": "^1.20.1",
"should": "^4.0.4",
"sinon": "^1.10.3",
"split": "^0.3.0",
"superagent": "^0.18.0"
"mocha": "^2.3.4",
"should": "^8.0.1",
"sinon": "^1.17.2",
"split": "^1.0.0",
"superagent": "^1.6.1"
}
}
13 changes: 6 additions & 7 deletions test/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@ describe('Async helper', function () {
var fn

beforeEach(function () {
ch = sinon.stub().returns(function (cb) { cb() })
ch = sinon.stub().returns(Promise.resolve())
fn = sinon.stub().yields(err, val)
})

it(
'should return a function with an arity of 1',
function () {
var thunk = async(ch, fn)
thunk.should.be.a.Function
thunk.length.should.be.exactly(1)
var promise = async(ch, fn)
promise.should.be.an.instanceOf(Promise)
}
)

Expand Down Expand Up @@ -60,11 +59,11 @@ describe('Async helper', function () {
'should call callback given to returned function',
function (done) {
var cb = sinon.spy()
async(ch, fn)(cb)
setImmediate(function () {
async(ch, fn).then(cb)
setTimeout(function () {
cb.callCount.should.be.exactly(1)
done()
})
}, 100)
}
)

Expand Down
29 changes: 12 additions & 17 deletions test/buffered.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ describe('A unbuffered channel', function () {
function (done) {
var ch = chan(0) // unbuffered
var cbCalled = false
ch('foo')(function () {
ch('foo').then((function () {
cbCalled = true
})
}))
setImmediate(function () {
expect(cbCalled).to.not.be.ok()
ch(function (err, val) {
setImmediate(function () {
setTimeout(function () {
expect(cbCalled).to.be.ok()
done()
})
}, 100)
})
})
}
Expand Down Expand Up @@ -58,14 +58,14 @@ describe('A buffered channel', function () {
var called = 0
var added = 0
while (++added <= buffer + 10) {
ch(added)(function (err) {
ch(added).then(function () {
called++
})
}
setImmediate(function () {
setTimeout(function () {
expect(called).to.be(buffer)
done()
})
}, 100)
}
)

Expand All @@ -79,16 +79,16 @@ describe('A buffered channel', function () {
var ch = chan(1)
var cbCalled = false
ch('foo')
ch('bar')(function () {
ch('bar').then(function () {
cbCalled = true
})
setImmediate(function () {
expect(cbCalled).to.not.be.ok()
ch(function (err, val) {
setImmediate(function () {
setTimeout(function () {
expect(cbCalled).to.be.ok()
done()
})
}, 100)
})
})
}
Expand All @@ -98,16 +98,11 @@ describe('A buffered channel', function () {
'should call cb with an error when the channel is closed before adding',
function (done) {
var ch = chan(0)
var cbCalled = false
ch('foo')(function (err) {
cbCalled = true
ch('foo').catch(function (err) {
expect(err).to.be.an(Error)
})
ch.close()
setImmediate(function () {
expect(cbCalled).to.be.ok()
done()
})
ch.close()
}
)

Expand Down
2 changes: 1 addition & 1 deletion test/close.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('A closed channel', function () {
function () {
var ch = chan()
ch.close()
ch('foo')(function (err) {
ch('foo').catch(function (err) {
expect(err).to.be.an(Error)
})
}
Expand Down