From 0719fa203c06012fad1550ea6915b500e0e66d8f Mon Sep 17 00:00:00 2001 From: Andrew Stewart Date: Thu, 18 Jun 2015 14:57:41 -0700 Subject: [PATCH] Remove dependency on 'async' This commit removes the last current dependency of Cylon, 'async'. In it's place, simplified versions of the methods used have been added so lib/utils/helpers.js. --- lib/cylon.js | 6 +-- lib/robot.js | 13 +++-- lib/utils/helpers.js | 67 ++++++++++++++++++++++++++ package.json | 5 -- spec/lib/utils/helpers.spec.js | 86 ++++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 16 deletions(-) diff --git a/lib/cylon.js b/lib/cylon.js index 4757fc0..9e30c3c 100644 --- a/lib/cylon.js +++ b/lib/cylon.js @@ -8,8 +8,6 @@ "use strict"; -var Async = require("async"); - var Logger = require("./logger"), Robot = require("./robot"), Config = require("./config"), @@ -113,7 +111,7 @@ Cylon.api = function api(Server, opts) { Cylon.start = function start() { var starters = _.pluck(this.robots, "start"); - Async.parallel(starters, function() { + _.parallel(starters, function() { var mode = Utils.fetch(Config, "workMode", "async"); if (mode === "sync") { @@ -157,7 +155,7 @@ Cylon.halt = function halt(callback) { var timeout = Config.haltTimeout || 3000; Utils.after(timeout, callback); - Async.parallel(fns, callback); + _.parallel(fns, callback); }; Cylon.toJSON = function() { diff --git a/lib/robot.js b/lib/robot.js index 17ebb58..2943b2a 100644 --- a/lib/robot.js +++ b/lib/robot.js @@ -16,8 +16,7 @@ var initializer = require("./initializer"), var validator = require("./validator"); -var Async = require("async"), - EventEmitter = require("events").EventEmitter; +var EventEmitter = require("events").EventEmitter; // used when creating default robot names var ROBOT_ID = 1; @@ -288,7 +287,7 @@ Robot.prototype.start = function(callback) { } }.bind(this); - Async.series([ + _.series([ this.startConnections, this.startDevices, start @@ -356,7 +355,7 @@ Robot.prototype.startConnections = function(callback) { }.bind(this); }, this); - return Async.parallel(starters, callback); + return _.parallel(starters, callback); }; /** @@ -386,7 +385,7 @@ Robot.prototype.startDevices = function(callback) { }; }, this); - return Async.parallel(starters, callback); + return _.parallel(starters, callback); }; /** @@ -406,8 +405,8 @@ Robot.prototype.halt = function(callback) { connections = _.pluck(this.connections, "disconnect"); try { - Async.parallel(devices, function() { - Async.parallel(connections, callback); + _.parallel(devices, function() { + _.parallel(connections, callback); }); } catch (e) { var msg = "An error occured while attempting to safely halt the robot"; diff --git a/lib/utils/helpers.js b/lib/utils/helpers.js index 0146dc1..49c75d1 100644 --- a/lib/utils/helpers.js +++ b/lib/utils/helpers.js @@ -8,6 +8,8 @@ "use strict"; +/* eslint no-use-before-define: 0 */ + var __slice = Array.prototype.slice; var H = module.exports = {}; @@ -210,3 +212,68 @@ function includes(arr, value) { extend(H, { includes: includes }); + +function parallel(functions, done) { + var total = functions.length, + completed = 0, + results = [], + error; + + function callback(err, result) { + if (error) { + return; + } + + if (err || error) { + error = err; + done(err); + return; + } + + completed++; + results.push(result); + + if (completed === total) { + done(null, results); + } + } + + if (!functions.length) { done(); } + + functions.forEach(function(fn) { fn(callback); }); +} + +extend(H, { + parallel: parallel +}); + +function series(functions, done) { + var results = [], + error; + + function callback(err, result) { + if (err || error) { + error = err; + return done(err); + } + + results.push(result); + + if (!functions.length) { + return done(null, results); + } + + next(); + } + + function next() { + functions.shift()(callback); + } + + if (!functions.length) { done(null, results); } + next(); +} + +extend(H, { + series: series +}); diff --git a/package.json b/package.json index 229260e..04bf646 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "hardware": { "*": false, "./": false, - "async": true, "./lib": true }, @@ -51,9 +50,5 @@ "mocha": "2.2.4", "sinon": "1.14.1", "eslint": "0.22.1" - }, - - "dependencies": { - "async": "0.9.0" } } diff --git a/spec/lib/utils/helpers.spec.js b/spec/lib/utils/helpers.spec.js index 8fe72e9..93733e7 100644 --- a/spec/lib/utils/helpers.spec.js +++ b/spec/lib/utils/helpers.spec.js @@ -289,4 +289,90 @@ describe("Helpers", function() { expect(fn(arr, {})).to.be.eql(false); }); }); + + describe("#parallel", function() { + var fn1, fn2, fn3, callback; + + beforeEach(function() { + fn1 = stub(); + fn2 = stub(); + fn3 = stub(); + callback = stub(); + }); + + it("executes a set of functions in parallel", function() { + _.parallel([fn1, fn2, fn3], callback); + + expect(fn1).to.be.called; + expect(fn2).to.be.called; + expect(fn3).to.be.called; + expect(callback).to.not.be.called; + + fn1.yield(null, true); + expect(callback).to.not.be.called; + fn2.yield(null, true); + expect(callback).to.not.be.called; + fn3.yield(null, true); + + expect(callback).to.be.calledWith(null, [true, true, true]); + }); + + it("stops immediately if there's an error", function() { + _.parallel([fn1, fn2, fn3], callback); + + fn1.yield(true, null); + + expect(callback).to.be.calledWith(true); + + fn2.yields(null, true); + fn3.yields(null, true); + + expect(callback).to.be.calledOnce; + }); + }); + + describe("#series", function() { + var fn1, fn2, fn3, callback; + + beforeEach(function() { + fn1 = stub(); + fn2 = stub(); + fn3 = stub(); + callback = stub(); + }); + + it("executes a set of functions in series", function() { + _.series([fn1, fn2, fn3], callback); + + expect(fn1).to.be.called; + expect(fn2).to.not.be.called; + expect(fn3).to.not.be.called; + expect(callback).to.not.be.called; + + fn1.yield(null, true); + + expect(fn2).to.be.called; + expect(fn3).to.not.be.called; + expect(callback).to.not.be.called; + + fn2.yield(null, true); + + expect(fn3).to.be.called; + expect(callback).to.not.be.called; + + fn3.yield(null, true); + + expect(callback).to.be.calledWith(null, [true, true, true]); + }); + + it("stops immediately if there's an error", function() { + _.series([fn1, fn2, fn3], callback); + + fn1.yield(true, null); + + expect(fn2).to.not.be.called; + expect(fn3).to.not.be.called; + expect(callback).to.be.calledWith(true); + }); + }); });