diff --git a/README.md b/README.md index c32c34d..7b5f88a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # assignment_async_nodejs Async Node.js sprint + +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..61fe221 --- /dev/null +++ b/data/test.txt @@ -0,0 +1,2 @@ +Hello! +Hello again! diff --git a/index.js b/index.js new file mode 100644 index 0000000..8a0c5ff --- /dev/null +++ b/index.js @@ -0,0 +1,269 @@ +// +//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 +// +//////////////////////////////////////////////////////////////////////////// + +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 +*/ + +//////////////////////////////////////////////////////////////////////////// +// +// 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!\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); +}); + +//////////////////////////////////////////////////////////////////////////// +// +// 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/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/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 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" +}