From 13d42f6e53086c97beccc4fcd98d6d1ec0e41e6f Mon Sep 17 00:00:00 2001 From: DC Date: Sun, 17 Sep 2017 22:09:50 -0700 Subject: [PATCH 1/4] initiated --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c32c34d..16fc024 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # assignment_async_nodejs Async Node.js sprint + +by Dennisc C From 977031bb1d4c655c4ce60b82ae284206e71238f1 Mon Sep 17 00:00:00 2001 From: DC Date: Sun, 17 Sep 2017 22:10:38 -0700 Subject: [PATCH 2/4] completed up through 'warmups' --- index.js | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 0000000..fc366df --- /dev/null +++ b/index.js @@ -0,0 +1,165 @@ +// +//Assignment source: http://www.vikingcodeschool.com/dashboard#/professional-development-with-javascript/building-with-async-node-js +// + +//////////////////////////////////////////////////////////////////////////// +// +//1. Create a promise that resolves the message "Hello Promise!" after 1 second +// +//////////////////////////////////////////////////////////////////////////// + +var p = new Promise(function(resolve,reject) { + //var delayOk = setTimeout(function() {console.log('delay ...')}, 1000); + + if (true) { + //resolve('Hello Promise!'); + setTimeout(function() {resolve('Hello Promise!')}, 1000); + } else { + reject('REJECT'); + } +}); + +p.then(function(fromResolve) { + console.log(fromResolve); +}).catch(function(fromReject) { + console.log(fromReject); +}); + +//////////////////////////////////////////////////////////////////////////// +// +//2. Create a function with the following signature delay(milliseconds) +// +//////////////////////////////////////////////////////////////////////////// + +var delay = function(ms) { + return new Promise(function(resolve,reject) { + setTimeout(function() {resolve(ms)}, ms); + }); +}; + +var countDown = function(ms) { + if (ms > 0) { + console.log(ms); + return delay(ms - 100); + } + console.log('Done!'); +}; + +delay(1000) + .then(countDown) //=> 1000 + .then(countDown) //=> 900 + .then(countDown) //=> 800 + .then(countDown) //=> 700 + .then(countDown) //=> 600 + .then(countDown) //=> 500 + .then(countDown) //=> 400 + .then(countDown) //=> 300 + .then(countDown) //=> 200 + .then(countDown) //=> 100 + .then(countDown); //=> Done! + +//////////////////////////////////////////////////////////////////////////// +// +//3. Create a function that accepts a number and returns a promise that resolves that number squared +// * The promise should reject if it is not passed a number +// * Now map an array of integers 1 to 9 to an array of promises using the function above +// * Use Promise.all to get the result of all of the promises in the array +// +//////////////////////////////////////////////////////////////////////////// + +var square = function(num) { + return new Promise(function(resolve,reject) { + if (isNumeric(num)) { + //resolve(Math.pow(num,2)); + resolve(num * num); + } else { + reject(NaN); + }; + }); +}; + +function isNumeric(n) { + return !isNaN(parseFloat(n)) && isFinite(n); +} + +/* +//test square function +square('12').then(function(fromResolve) { + console.log(fromResolve); +}).catch(function(fromReject) { + console.log(fromReject); +}); +*/ + +var myArray = [1,2,3,4,5,6,7,8,9]; + +var mySquares = myArray.map(function(el) { + return square(el); +}); + +//Promise.all +Promise.all(mySquares).then(function(fromResolve){ + console.log(fromResolve); +}).catch(function(fromReject) { + console.log(fromReject); +}); + +//////////////////////////////////////////////////////////////////////////// +// +// 4. Create a function with this signature doBadThing(forRealz) +// +//////////////////////////////////////////////////////////////////////////// + +var doBadThing = function (forRealz) { + return new Promise(function(resolve,reject) { + if (isFalsy(forRealz)) { + resolve('Yay! (actually falsy)'); + } else { + reject('Boo ... (actually truthy)'); + }; + }); +}; + +function isFalsy(i) { + if ((i === false) || (i === null) || (i === undefined) || (i === NaN) || (i === 0) || (i === "")) { + return true; + } else { + return false; + }; +}; + +doBadThing(false).then(function(fromResolve) { + console.log('1) doBadThing: ' + fromResolve); +}).catch(function(fromReject) { + console.log('1) doBadThing: ' + fromReject); +}); + +doBadThing(true).then(function(fromResolve) { + console.log('2) doBadThing: ' + fromResolve); +}).catch(function(fromReject) { + console.log('2) doBadThing: ' + fromReject); +}); + +/* +doBadThing(true).then(function(fromResolve) { + console.log('3) doBadThing: ' + fromResolve); +}).then(function(fromReject) { + console.log('3) doBadThing: ' + fromReject); +}); +Result from (3) above is the following: +(node:15148) UnhandledPromiseRejectionWarning: Unhandled promise rejection (reje +ction id: 3): Boo ... (actually truthy) +(node:15148) [DEP0018] DeprecationWarning: Unhandled promise rejections are depr +ecated. In the future, promise rejections that are not handled will terminate th +e Node.js process with a non-zero exit code. +*/ + +doBadThing(false).then(function(fromResolve) { + console.log('4) doBadThing: ' + fromResolve); + throw new Error("Thrown from .then and expect to be caught in .catch"); +}).catch(function(fromReject) { + console.log('4) doBadThing: ' + fromReject); +}); +/* +Result from (4) above is that it goes to both the .then clause, and the .catch clause +*/ From b158b1c7e687e710dfaa92507b40612e85159a22 Mon Sep 17 00:00:00 2001 From: DC Date: Mon, 18 Sep 2017 13:44:39 -0700 Subject: [PATCH 3/4] completed up through 'file operations' --- README.md | 2 +- data/lorem.txt | 6 ++++++ data/test.txt | 2 ++ index.js | 34 +++++++++++++++++++++++++++++++++- lib/fsp.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 22 ++++++++++++++++++++++ 6 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 data/lorem.txt create mode 100644 data/test.txt create mode 100644 lib/fsp.js create mode 100644 package.json diff --git a/README.md b/README.md index 16fc024..7b5f88a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ # assignment_async_nodejs Async Node.js sprint -by Dennisc C +by Dennis C diff --git a/data/lorem.txt b/data/lorem.txt new file mode 100644 index 0000000..5f5e1e0 --- /dev/null +++ b/data/lorem.txt @@ -0,0 +1,6 @@ +Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod +tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo +consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse +cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non +proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file diff --git a/data/test.txt b/data/test.txt new file mode 100644 index 0000000..0ba8ab3 --- /dev/null +++ b/data/test.txt @@ -0,0 +1,2 @@ +Hello DC! +Hello again! diff --git a/index.js b/index.js index fc366df..ac64c2f 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,5 @@ +var fsp = require('./lib/fsp.js'); +// // //Assignment source: http://www.vikingcodeschool.com/dashboard#/professional-development-with-javascript/building-with-async-node-js // @@ -121,7 +123,7 @@ var doBadThing = function (forRealz) { }; function isFalsy(i) { - if ((i === false) || (i === null) || (i === undefined) || (i === NaN) || (i === 0) || (i === "")) { + if ((i === false) || (i === null) || (i === undefined) || (i === NaN) || (i === 0) || (i === '')) { return true; } else { return false; @@ -163,3 +165,33 @@ doBadThing(false).then(function(fromResolve) { /* Result from (4) above is that it goes to both the .then clause, and the .catch clause */ + +//////////////////////////////////////////////////////////////////////////// +// +// 5. File Operations and creating own module +// * Create a fsp module that wraps these fs methods +// and makes the following promise based versions possible ... +// +//////////////////////////////////////////////////////////////////////////// + +fsp.readFile('./data/lorem.txt').then(function(data) { + // Outputs the file data + console.log(data); +}).catch(function(err) { + console.log(err); +}); + +fsp.writeFile('./data/test.txt', 'Hello DC!\n').then(function(res) { + // Outputs the file data after writing + console.log(res); +}).catch(function(err) { + console.error(err); +}); + +//fsp.appendFile('./data/test.txt', 'Hello again!\n'); +fsp.appendFile('./data/test.txt', 'Hello again!\n').then(function(res) { + // Outputs the file data after appending + console.log(res); +}).catch(function(err) { + console.error(err); +}); diff --git a/lib/fsp.js b/lib/fsp.js new file mode 100644 index 0000000..7b3191c --- /dev/null +++ b/lib/fsp.js @@ -0,0 +1,47 @@ +const fs = require('fs'); + +/* +//test code +fsp.readFile('./test.txt', 'utf8', function(err, data) { + console.log('done reading file'); +}); + +fsp.writeFile('./writetome.txt', '>>WRITE STUFF<<\n', 'utf8', function(err, data) { + console.log('done writing file'); +}); + +fsp.appendFile('./writetome.txt', '>>APPEND STUFF<<', 'utf8', function(err, data) { + console.log('done appending stuff'); +}); +*/ + +const fsp = { + readFile: function(path) { + return new Promise(function(resolve,reject) { + fs.readFile(path, 'utf8', function(err, data){ + if (err) reject(err); + else resolve(data); + }); + }); + }, + writeFile: function(path, stuff) { + return new Promise(function(resolve,reject) { + //note: writeFile callback only returns err, no data like readFile + fs.writeFile(path, stuff, 'utf8', function(err) { + if (err) reject(err); + else resolve('>>Done with write<<'); + }); + }); + }, + appendFile: function(path, stuff) { + return new Promise(function(resolve,reject) { + //note: appendFile callback only returns err, no data like readFile + fs.appendFile(path, stuff, 'utf8', function(err) { + if (err) reject(err); + else resolve('>>Done with append<<'); + }); + }); + } +}; + +module.exports = fsp; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..8bf1f7b --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "assignment_async_nodejs", + "version": "1.0.0", + "description": "Async Node.js sprint", + "main": "index.js", + "directories": { + "lib": "lib" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/heyyodc-git/assignment_async_nodejs.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/heyyodc-git/assignment_async_nodejs/issues" + }, + "homepage": "https://github.com/heyyodc-git/assignment_async_nodejs#readme" +} From 907437aacb799a0fed0e379ccf4eff7ba2dfd52c Mon Sep 17 00:00:00 2001 From: DC Date: Tue, 19 Sep 2017 12:31:21 -0700 Subject: [PATCH 4/4] completed! --- data/test.txt | 2 +- index.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++--- lib/myEvents.js | 53 ++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 lib/myEvents.js diff --git a/data/test.txt b/data/test.txt index 0ba8ab3..61fe221 100644 --- a/data/test.txt +++ b/data/test.txt @@ -1,2 +1,2 @@ -Hello DC! +Hello! Hello again! diff --git a/index.js b/index.js index ac64c2f..8a0c5ff 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,23 @@ -var fsp = require('./lib/fsp.js'); -// // //Assignment source: http://www.vikingcodeschool.com/dashboard#/professional-development-with-javascript/building-with-async-node-js // +const fsp = require('./lib/fsp.js'); + +//use node's Emitter +//const Emitter = require('events'); + +//use my Emitter +const Emitter = require('./lib/myEvents.js'); +//Emitter is now the function constructor + +// now make emitter from the function constructor (Emitter) +const emitter = new Emitter(); +// emitter is now a fully constructed object +//in other words, these are now ready to use: +// ... emitter.on() +// ... emitter.emit() + //////////////////////////////////////////////////////////////////////////// // //1. Create a promise that resolves the message "Hello Promise!" after 1 second @@ -142,12 +156,12 @@ doBadThing(true).then(function(fromResolve) { console.log('2) doBadThing: ' + fromReject); }); -/* doBadThing(true).then(function(fromResolve) { console.log('3) doBadThing: ' + fromResolve); }).then(function(fromReject) { console.log('3) doBadThing: ' + fromReject); }); +/* Result from (3) above is the following: (node:15148) UnhandledPromiseRejectionWarning: Unhandled promise rejection (reje ction id: 3): Boo ... (actually truthy) @@ -181,7 +195,7 @@ fsp.readFile('./data/lorem.txt').then(function(data) { console.log(err); }); -fsp.writeFile('./data/test.txt', 'Hello DC!\n').then(function(res) { +fsp.writeFile('./data/test.txt', 'Hello!\n').then(function(res) { // Outputs the file data after writing console.log(res); }).catch(function(err) { @@ -195,3 +209,61 @@ fsp.appendFile('./data/test.txt', 'Hello again!\n').then(function(res) { }).catch(function(err) { console.error(err); }); + +//////////////////////////////////////////////////////////////////////////// +// +// 6. Create an Event Emitter from Scratch +// +//////////////////////////////////////////////////////////////////////////// + + +//register some listeners +emitter.on('click', function() { + console.log('clicked - 1'); +}); + +emitter.on('click', function() { + console.log('clicked - 2'); +}); + +emitter.on('open', function() { + console.log('open - 1'); +}); + +emitter.on('close', function() { + console.log('close - 1'); +}); + +emitter.on('jump', function() { + console.log('jump - 1'); +}); + +emitter.on('swim', function() { + console.log('swim - 1'); +}); + +//emit! +emitter.emit('click'); + +//de-register listeners +emitter.removeListener('click'); + +//emit to check that listeners have been de-registered +emitter.emit('click'); + +//emit others +emitter.emit('jump'); +emitter.emit('open'); +emitter.emit('close'); +emitter.emit('swim'); + +//de-register ALL listeners +//note: my removeAllListeners spec diff than node.js' emitter, and will produce errors when using node.js' version +emitter.removeAllListeners(); + +//emit to check that ALL listeners have been de-registered +emitter.emit('click'); +emitter.emit('jump'); +emitter.emit('open'); +emitter.emit('close'); +emitter.emit('swim'); diff --git a/lib/myEvents.js b/lib/myEvents.js new file mode 100644 index 0000000..7d389ee --- /dev/null +++ b/lib/myEvents.js @@ -0,0 +1,53 @@ +'use strict'; + +function Emitter() { + this.events = {}; +} + +//on method creates way to register event listeners +//listener stores function code +Emitter.prototype.on = function(type, listener) { + //listeners will be contained in an array data structure, that sits in the event object, simply as a property + this.events[type] = this.events[type] || []; + this.events[type].push(listener); +} + +//emitter method to trigger event happened +//listener stores function code +Emitter.prototype.emit = function(type) { + if (this.events[type]) { + this.events[type].forEach(function(listener) { + listener(); + }); + } +} + +Emitter.prototype.removeListener = function(type) { + if (this.events[type]) { + //clear the values of this type (event) only + delete this.events[type]; + } +} + +//note: my spec of removeAllListeners slightly different than node.js' version +Emitter.prototype.removeAllListeners = function() { + var o = Object.keys(this.events); // stores all listener types in an array + var ol = o.length; // stores listener count + console.log('Before: Total num of listeners registered = ' + ol); + console.log('Before: Listeners registered are: '); + console.log(o); // print all listener types + + // clear all values in all listeners + var oo = this.events; + o.forEach(function(element, index) { + delete oo[element]; + }); + + o = Object.keys(this.events); // requery + ol = o.length; // requery + console.log('After: Total num of listeners registered = ' + ol); + console.log('After: Listeners registered are: '); + console.log(o); // print all listener types +} + +module.exports = Emitter; \ No newline at end of file