Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support synchronous mode

  • Loading branch information...
commit d6969ea50438f4940cdb2d7d2c8914073f0714eb 1 parent baee495
@wdavidw authored
Showing with 94 additions and 20 deletions.
  1. +2 −0  doc/index.md
  2. +32 −11 lib/each.js
  3. +23 −9 src/each.coffee
  4. +37 −0 test/sync.coffee
View
2  doc/index.md
@@ -111,6 +111,8 @@ The following functions are available:
for more details about the different modes.
- `times`
Repeat operation multiple times.
+- `sync`
+ Run callbacks in synchronous mode, no next callback are provided, may throw or return an error.
- `files`
Emit file paths based on a directory or globbing expression.
View
43 lib/each.js
@@ -5,7 +5,13 @@ glob = require('glob');
/*
each(elements)
-.mode(parallel=false|true|integer)
+.parallel(false|true|integer)
+.sync(false)
+.times(1)
+.files('./*.coffee')
+.write(element)
+.pause()
+.resume()
.on('item', callback)
.on('error', callback)
.on('end', callback)
@@ -15,7 +21,7 @@ Chained and parallel async iterator in one elegant function
module.exports = function(elements) {
- var arglength, eacher, endable, errors, events, isObject, keys, next, parallel, run, times, type;
+ var arglength, eacher, endable, errors, events, isObject, keys, next, parallel, run, sync, times, type;
type = typeof elements;
if (elements === null || type === 'undefined') {
elements = [];
@@ -41,6 +47,7 @@ module.exports = function(elements) {
eacher.total = keys ? keys.length : elements.length;
eacher.started = 0;
eacher.done = 0;
+ sync = false;
times = 1;
endable = 1;
eacher.paused = 0;
@@ -77,6 +84,10 @@ module.exports = function(elements) {
}
return eacher;
};
+ eacher.sync = function(s) {
+ sync = s;
+ return eacher;
+ };
eacher.times = function(t) {
times = t;
if (elements.length === 0) {
@@ -113,7 +124,7 @@ module.exports = function(elements) {
return eacher;
};
run = function() {
- var args, emit, err, error, index, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3;
+ var args, emit, err, error, index, l, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3;
if (eacher.paused) {
return;
}
@@ -171,27 +182,31 @@ module.exports = function(elements) {
_ref3 = events.item;
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
emit = _ref3[_l];
- switch (emit.length) {
+ l = emit.length;
+ if (sync) {
+ l++;
+ }
+ switch (l) {
case 1:
- args = [next];
+ args = [];
break;
case 2:
if (keys) {
- args = [elements[keys[index]], next];
+ args = [elements[keys[index]]];
} else {
- args = [elements[index], next];
+ args = [elements[index]];
}
break;
case 3:
if (keys) {
- args = [keys[index], elements[keys[index]], next];
+ args = [keys[index], elements[keys[index]]];
} else {
- args = [elements[index], index, next];
+ args = [elements[index], index];
}
break;
case 4:
if (keys) {
- args = [keys[index], elements[keys[index]], index, next];
+ args = [keys[index], elements[keys[index]], index];
} else {
return next(new Error('Invalid arguments in item callback'));
}
@@ -199,7 +214,13 @@ module.exports = function(elements) {
default:
return next(new Error('Invalid arguments in item callback'));
}
- emit.apply(null, args);
+ if (!sync) {
+ args.push(next);
+ }
+ err = emit.apply(null, args);
+ if (sync) {
+ next(err);
+ }
}
} catch (e) {
if (eacher.readable) {
View
32 src/each.coffee
@@ -3,7 +3,13 @@ glob = require 'glob'
###
each(elements)
-.mode(parallel=false|true|integer)
+.parallel(false|true|integer)
+.sync(false)
+.times(1)
+.files('./*.coffee')
+.write(element)
+.pause()
+.resume()
.on('item', callback)
.on('error', callback)
.on('end', callback)
@@ -32,6 +38,7 @@ module.exports = (elements) ->
eacher.total = if keys then keys.length else elements.length
eacher.started = 0
eacher.done = 0
+ sync = false
times = 1
endable = 1
eacher.paused = 0
@@ -60,6 +67,9 @@ module.exports = (elements) ->
# Sequential (in case parallel is called multiple times)
else parallel = 1
eacher
+ eacher.sync = (s) ->
+ sync = s
+ eacher
eacher.times = (t) ->
times = t
eacher.write null if elements.length is 0
@@ -118,24 +128,28 @@ module.exports = (elements) ->
eacher.started++
try
for emit in events.item
- switch emit.length
+ l = emit.length
+ l++ if sync
+ switch l
when 1
- args = [next]
+ args = []
when 2
if keys
- then args = [elements[keys[index]], next]
- else args = [elements[index], next]
+ then args = [elements[keys[index]]]
+ else args = [elements[index]]
when 3
if keys
- then args = [keys[index], elements[keys[index]], next]
- else args = [elements[index], index, next]
+ then args = [keys[index], elements[keys[index]]]
+ else args = [elements[index], index]
when 4
if keys
- then args = [keys[index], elements[keys[index]], index, next]
+ then args = [keys[index], elements[keys[index]], index]
else return next new Error 'Invalid arguments in item callback'
else
return next new Error 'Invalid arguments in item callback'
- emit args...
+ args.push next unless sync
+ err = emit args...
+ next err if sync
catch e
# prevent next to be called if an error occurend inside the
# error, end or both callbacks
View
37 test/sync.coffee
@@ -0,0 +1,37 @@
+
+should = require 'should'
+each = if process.env.EACH_COV then require '../lib-cov/each' else require '../lib/each'
+
+describe 'sync', ->
+ it 'run item event synchronously', (next) ->
+ current = 0
+ each( [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] )
+ .parallel( 4 )
+ .sync( true )
+ .on 'item', (element, index) ->
+ index.should.eql current
+ element.should.eql current
+ current++
+ .on 'end', ->
+ current.should.eql 10
+ next()
+ it 'emit thrown error', (next) ->
+ current = 0
+ each( [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] )
+ .parallel( 4 )
+ .sync( true )
+ .on 'item', (element, index) ->
+ throw new Error 'Argh'
+ .on 'error', (err) ->
+ err.message.should.eql 'Argh'
+ next()
+ it 'emit returned error', (next) ->
+ current = 0
+ each( [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] )
+ .parallel( 4 )
+ .sync( true )
+ .on 'item', (element, index) ->
+ return new Error 'Argh'
+ .on 'error', (err) ->
+ err.message.should.eql 'Argh'
+ next()
Please sign in to comment.
Something went wrong with that request. Please try again.