From 866bfb9a8dac99b121dbfa6464a2ed358c085a0e Mon Sep 17 00:00:00 2001 From: Ilya Shatokhin Date: Tue, 22 Mar 2016 03:09:59 -0300 Subject: [PATCH 1/3] Add support for ES2015 iterators --- lib/internal/eachOfLimit.js | 10 +++++----- lib/internal/iterator.js | 40 +++++++++++++++++++++++++++++++++++++ test/test-async.js | 30 ++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 lib/internal/iterator.js diff --git a/lib/internal/eachOfLimit.js b/lib/internal/eachOfLimit.js index 4b7c7efa9..53d05b3a2 100644 --- a/lib/internal/eachOfLimit.js +++ b/lib/internal/eachOfLimit.js @@ -3,14 +3,14 @@ import noop from 'lodash/noop'; import once from 'lodash/once'; -import keyIterator from './keyIterator'; +import iterator from './iterator'; import onlyOnce from './onlyOnce'; export default function _eachOfLimit(limit) { return function (obj, iteratee, callback) { callback = once(callback || noop); obj = obj || []; - var nextKey = keyIterator(obj); + var nextElem = iterator(obj); if (limit <= 0) { return callback(null); } @@ -24,8 +24,8 @@ export default function _eachOfLimit(limit) { } while (running < limit && !errored) { - var key = nextKey(); - if (key === null) { + var elem = nextElem(); + if (elem === null) { done = true; if (running <= 0) { callback(null); @@ -33,7 +33,7 @@ export default function _eachOfLimit(limit) { return; } running += 1; - iteratee(obj[key], key, onlyOnce(function (err) { + iteratee(elem.value, elem.key, onlyOnce(function (err) { running -= 1; if (err) { callback(err); diff --git a/lib/internal/iterator.js b/lib/internal/iterator.js new file mode 100644 index 000000000..8f245f285 --- /dev/null +++ b/lib/internal/iterator.js @@ -0,0 +1,40 @@ +'use strict'; + +import isArrayLike from 'lodash/isArrayLike'; +import keys from 'lodash/keys'; +import isMap from 'lodash/isMap'; + +var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator; + +export default function iterator(coll) { + var i = -1; + var len; + if (isArrayLike(coll)) { + len = coll.length; + return function next() { + i++; + return i < len ? {value: coll[i], key: i} : null; + }; + } + + if (iteratorSymbol && coll[iteratorSymbol]) { + var iterate = coll[iteratorSymbol](); + var map = isMap(coll); + + return function next() { + var item = iterate.next(); + if (item.done) + return null; + i++; + return map ? {value: item.value[1], key: item.value[0]} : {value: item.value, key: i}; + }; + } + + var okeys = keys(coll); + len = okeys.length; + return function next() { + i++; + var key = okeys[i]; + return i < len ? {value: coll[key], key: key} : null; + }; +} diff --git a/test/test-async.js b/test/test-async.js index f12d7c170..101328faa 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -867,6 +867,36 @@ exports['forEachOf with array'] = function(test){ }); }; +exports['forEachOf with Set (iterators)'] = function(test){ + if (typeof Set !== 'function') + return test.done(); + + var args = []; + var set = new Set(); + set.add("a"); + set.add("b"); + async.forEachOf(set, forEachOfIteratee.bind(this, args), function(err){ + if (err) throw err; + test.same(args, [0, "a", 1, "b"]); + test.done(); + }); +}; + +exports['forEachOf with Map (iterators)'] = function(test){ + if (typeof Map !== 'function') + return test.done(); + + var args = []; + var map = new Map(); + map.set(1, "a"); + map.set(2, "b"); + async.forEachOf(map, forEachOfIteratee.bind(this, args), function(err){ + if (err) throw err; + test.same(args, [1, "a", 2, "b"]); + test.done(); + }); +}; + exports['eachSeries'] = function(test){ var args = []; async.eachSeries([1,3,2], eachIteratee.bind(this, args), function(err){ From aec7038cdf5b6641abeda5545bff2c18104ba156 Mon Sep 17 00:00:00 2001 From: Ilya Shatokhin Date: Tue, 22 Mar 2016 03:30:00 -0300 Subject: [PATCH 2/3] Added new tests --- lib/internal/keyIterator.js | 23 --------------- test/test-async.js | 59 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 23 deletions(-) delete mode 100644 lib/internal/keyIterator.js diff --git a/lib/internal/keyIterator.js b/lib/internal/keyIterator.js deleted file mode 100644 index 0e2b0c348..000000000 --- a/lib/internal/keyIterator.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -import isArrayLike from 'lodash/isArrayLike'; -import keys from 'lodash/keys'; - -export default function keyIterator(coll) { - var i = -1; - var len; - if (isArrayLike(coll)) { - len = coll.length; - return function next() { - i++; - return i < len ? i : null; - }; - } else { - var okeys = keys(coll); - len = okeys.length; - return function next() { - i++; - return i < len ? okeys[i] : null; - }; - } -} diff --git a/test/test-async.js b/test/test-async.js index 101328faa..0755eb103 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -1146,6 +1146,35 @@ exports['forEachOfSeries with array'] = function(test){ }); }; +exports['forEachOfSeries with Set (iterators)'] = function(test){ + if (typeof Set !== 'function') + return test.done(); + + var args = []; + var set = new Set(); + set.add("a"); + set.add("b"); + async.forEachOfSeries(set, forEachOfIteratee.bind(this, args), function(err){ + if (err) throw err; + test.same(args, [0, "a", 1, "b"]); + test.done(); + }); +}; + +exports['forEachOfSeries with Map (iterators)'] = function(test){ + if (typeof Map !== 'function') + return test.done(); + + var args = []; + var map = new Map(); + map.set(1, "a"); + map.set(2, "b"); + async.forEachOfSeries(map, forEachOfIteratee.bind(this, args), function(err){ + if (err) throw err; + test.same(args, [1, "a", 2, "b"]); + test.done(); + }); +}; exports['eachOfLimit alias'] = function(test){ test.equals(async.eachOfLimit, async.forEachOfLimit); @@ -1263,6 +1292,36 @@ exports['forEachOfLimit with array'] = function(test){ }); }; +exports['forEachOfLimit with Set (iterators)'] = function(test){ + if (typeof Set !== 'function') + return test.done(); + + var args = []; + var set = new Set(); + set.add("a"); + set.add("b"); + async.forEachOfLimit(set, 1, forEachOfIteratee.bind(this, args), function(err){ + if (err) throw err; + test.same(args, [0, "a", 1, "b"]); + test.done(); + }); +}; + +exports['forEachOfLimit with Map (iterators)'] = function(test){ + if (typeof Map !== 'function') + return test.done(); + + var args = []; + var map = new Map(); + map.set(1, "a"); + map.set(2, "b"); + async.forEachOfLimit(map, 1, forEachOfIteratee.bind(this, args), function(err){ + if (err) throw err; + test.same(args, [1, "a", 2, "b"]); + test.done(); + }); +}; + exports['map'] = { 'basic': function(test){ From 4c949792d802d2bfa3acefc9cc318e145646e2e6 Mon Sep 17 00:00:00 2001 From: Ilya Shatokhin Date: Tue, 22 Mar 2016 12:48:04 -0300 Subject: [PATCH 3/3] Remove iterator index (Map). --- lib/internal/iterator.js | 4 +--- test/test-async.js | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/internal/iterator.js b/lib/internal/iterator.js index 8f245f285..d83203941 100644 --- a/lib/internal/iterator.js +++ b/lib/internal/iterator.js @@ -2,7 +2,6 @@ import isArrayLike from 'lodash/isArrayLike'; import keys from 'lodash/keys'; -import isMap from 'lodash/isMap'; var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator; @@ -19,14 +18,13 @@ export default function iterator(coll) { if (iteratorSymbol && coll[iteratorSymbol]) { var iterate = coll[iteratorSymbol](); - var map = isMap(coll); return function next() { var item = iterate.next(); if (item.done) return null; i++; - return map ? {value: item.value[1], key: item.value[0]} : {value: item.value, key: i}; + return {value: item.value, key: i}; }; } diff --git a/test/test-async.js b/test/test-async.js index 0755eb103..047c7f9fc 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -892,7 +892,7 @@ exports['forEachOf with Map (iterators)'] = function(test){ map.set(2, "b"); async.forEachOf(map, forEachOfIteratee.bind(this, args), function(err){ if (err) throw err; - test.same(args, [1, "a", 2, "b"]); + test.same(args, [0, [1, "a"], 1, [2, "b"]]); test.done(); }); }; @@ -1171,7 +1171,7 @@ exports['forEachOfSeries with Map (iterators)'] = function(test){ map.set(2, "b"); async.forEachOfSeries(map, forEachOfIteratee.bind(this, args), function(err){ if (err) throw err; - test.same(args, [1, "a", 2, "b"]); + test.same(args, [0, [1, "a"], 1, [2, "b"]]); test.done(); }); }; @@ -1317,7 +1317,7 @@ exports['forEachOfLimit with Map (iterators)'] = function(test){ map.set(2, "b"); async.forEachOfLimit(map, 1, forEachOfIteratee.bind(this, args), function(err){ if (err) throw err; - test.same(args, [1, "a", 2, "b"]); + test.same(args, [0, [1, "a"], 1, [2, "b"]]); test.done(); }); };