From 5f1bbc900499de96a42a37b908f985db9fb3cbaf Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Thu, 27 Aug 2015 21:39:50 +0200 Subject: [PATCH] ecma6: Promise --- ecma6/.jscsrc | 80 +++++++++++++++++++++++++++++ ecma6/.jshintrc | 70 +++++++++++++++++++++++++ ecma6/promise/index.html | 12 +++++ ecma6/promise/promise.js | 72 ++++++++++++++++++++++++++ ecma6/promise/promisexhr.js | 121 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 355 insertions(+) create mode 100644 ecma6/.jscsrc create mode 100644 ecma6/.jshintrc create mode 100644 ecma6/promise/index.html create mode 100644 ecma6/promise/promise.js create mode 100644 ecma6/promise/promisexhr.js diff --git a/ecma6/.jscsrc b/ecma6/.jscsrc new file mode 100644 index 0000000..be714a3 --- /dev/null +++ b/ecma6/.jscsrc @@ -0,0 +1,80 @@ +{ + "excludeFiles": ["node_modules/**", "bower_components/**"], + + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "requireOperatorBeforeLineBreak": true, + "requireCamelCaseOrUpperCaseIdentifiers": true, + "maximumLineLength": { + "value": 120, + "allowComments": true, + "allowRegex": true + }, + "validateIndentation": 2, + "validateQuoteMarks": "'", + + "disallowMultipleLineStrings": true, + "disallowMixedSpacesAndTabs": true, + "disallowTrailingWhitespace": true, + "disallowSpaceAfterPrefixUnaryOperators": true, + "disallowMultipleVarDecl": null, + + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBinaryOperators": [ + "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", + "&=", "|=", "^=", "+=", + + "+", "-", "*", "/", "%", "<<", ">>", ">>>", "&", + "|", "^", "&&", "||", "===", "==", ">=", + "<=", "<", ">", "!=", "!==" + ], + "requireSpaceAfterBinaryOperators": true, + "requireSpacesInConditionalExpression": true, + "requireSpaceBeforeBlockStatements": true, + "requireLineFeedAtFileEnd": true, + "disallowSpacesInsideObjectBrackets": "all", + "disallowSpacesInsideArrayBrackets": "all", + "disallowSpacesInsideParentheses": true, + + "jsDoc": { + "checkAnnotations": { + "preset": "jsdoc3", + "extra": { + "ngdoc": true, + "methodOf": true + } + }, + "checkParamNames": true, + "requireParamTypes": true, + "checkReturnTypes": true, + "checkTypes": true + }, + + "disallowMultipleLineBreaks": true, + + "disallowCommaBeforeLineBreak": null, + "disallowDanglingUnderscores": null, + "disallowEmptyBlocks": null, + "disallowTrailingComma": null, + "requireCommaBeforeLineBreak": null, + "requireDotNotation": null, + "requireMultipleVarDecl": null, + "requireParenthesesAroundIIFE": true +} diff --git a/ecma6/.jshintrc b/ecma6/.jshintrc new file mode 100644 index 0000000..3a19927 --- /dev/null +++ b/ecma6/.jshintrc @@ -0,0 +1,70 @@ +{ + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "es3": false, + "forin": true, + "freeze": true, + "immed": true, + "indent": 2, + "latedef": "nofunc", + "newcap": true, + "noarg": true, + "noempty": true, + "nonbsp": true, + "nonew": true, + "plusplus": false, + "quotmark": "single", + "undef": true, + "unused": false, + "strict": false, + "maxparams": 10, + "maxdepth": 5, + "maxstatements": 40, + "maxcomplexity": 8, + "maxlen": 120, + + "asi": false, + "boss": false, + "debug": false, + "eqnull": true, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": false, + "laxcomma": false, + "loopfunc": true, + "maxerr": 9999, + "moz": false, + "multistr": false, + "notypeof": false, + "proto": false, + "scripturl": false, + "shadow": false, + "sub": true, + "supernew": false, + "validthis": false, + "noyield": false, + + "browser": true, + "node": true, + + "globals": { + "angular": false, + /* Jasmine */ + "describe" : false, + "expect" : false, + "inject" : false, + "it" : false, + "before" : false, + "beforeEach" : false, + "after" : false, + "afterEach" : false, + "spyOn" : false + } +} diff --git a/ecma6/promise/index.html b/ecma6/promise/index.html new file mode 100644 index 0000000..802b2ee --- /dev/null +++ b/ecma6/promise/index.html @@ -0,0 +1,12 @@ + + + + + + +
+
+ + + + diff --git a/ecma6/promise/promise.js b/ecma6/promise/promise.js new file mode 100644 index 0000000..98dd475 --- /dev/null +++ b/ecma6/promise/promise.js @@ -0,0 +1,72 @@ +(function () { + 'use strict'; + + var promiseCount = 0; + var log = document.getElementById('log'); + + function testPromise() { + var thisPromiseCount = ++promiseCount; + + var log = document.getElementById('log'); + log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Started (Sync code started)
'); + + // We make a new promise: we promise the string 'result' (after waiting 3s) + var p1 = new Promise( + // The resolver function is called with the ability to resolve or + // reject the promise + function(resolve, reject) { + log.insertAdjacentHTML('beforeend', thisPromiseCount + + ') Promise started (Async code started)
'); + // This only is an example to create asynchronism + window.setTimeout( + function() { + // We fulfill the promise! + resolve(thisPromiseCount); + // We reject the promise! + //reject(thisPromiseCount); + }, Math.random() * 2000 + 1000); + }); + + // We define what to do when the promise is fulfilled + // but we only call this if the promise is resolved/fulfilled + p1.then( + // Just log the message and a value + function(val) { + log.insertAdjacentHTML('beforeend', val + ') Promise fulfilled 1 (Async code terminated)
'); + return val; + }) + .catch( + // Rejected promises are passed on by Promise.prototype.then(onFulfilled) + function(reason) { + log.insertAdjacentHTML('beforeend', 'Handle rejected promise 1 (' + reason + ') here
'); + return reason; + }) + .then( + function(val) { + // val, value coming from line 36. Because a fulfilled promise was handled the next promise + // resolves to the return value of the called handler. If there is no return in line 36, here, val would be + // undefined :( + + // val, value coming from line 42. If there is no return in line 42, here, val would be undefined :( + log.insertAdjacentHTML('beforeend', val + ') Promise fulfilled 2 (Async code terminated)
'); + }) + .catch( + function(reason) { + // It is never used because the return value from catch goes to the onFulfilled callback in line 45 :( + log.insertAdjacentHTML('beforeend', 'Handle rejected promise 2 (' + reason + ') here
'); + } + ); + + log.insertAdjacentHTML('beforeend', thisPromiseCount + + ') Promise made (Sync code terminated)
'); + } + + if ('Promise' in window) { + var btn = document.getElementById('btn'); + btn.addEventListener('click', testPromise); + } + else { + log.innerHTML = 'Live example not available as your browser does not support the Promise interface.'; + } + +}()); diff --git a/ecma6/promise/promisexhr.js b/ecma6/promise/promisexhr.js new file mode 100644 index 0000000..6d081ef --- /dev/null +++ b/ecma6/promise/promisexhr.js @@ -0,0 +1,121 @@ +(function () { + 'use strict'; + + var log = document.getElementById('log'); + + // A-> $http function is implemented in order to follow the standard Adapter pattern + function $http(url) { + + // A small example of object + var core = { + + // Method that performs the ajax request + ajax : function (method, url, args) { + + // Creating a promise + var promise = new Promise(function (resolve, reject) { + + // Instantiates the XMLHttpRequest + var client = new XMLHttpRequest(); + var uri = url; + + if (args && (method === 'POST' || method === 'PUT')) { + uri += '?'; + var argcount = 0; + for (var key in args) { + if (args.hasOwnProperty(key)) { + if (argcount++) { + uri += '&'; + } + uri += encodeURIComponent(key) + '=' + encodeURIComponent(args[key]); + } + } + } + + client.open(method, uri); + client.send(); + + client.onload = function () { + if (this.status === 200) { + // Performs the function "resolve" when this.status is equal to 200 + resolve(this.response); + } else { + // Performs the function "reject" when this.status is different than 200 + reject(this.statusText); + } + }; + client.onerror = function () { + reject(this.statusText); + }; + }); + + // Return the promise + return promise; + } + }; + + // Adapter pattern + return { + 'get' : function(args) { + return core.ajax('GET', url, args); + }, + 'post' : function(args) { + return core.ajax('POST', url, args); + }, + 'put' : function(args) { + return core.ajax('PUT', url, args); + }, + 'delete' : function(args) { + return core.ajax('DELETE', url, args); + } + }; + } + // End A + + function testPromise() { + // B-> Here you define its functions and its payload + var mdnAPI = 'https://developer.mozilla.org/en-US/search.json'; + var payload = { + 'topic' : 'js', + 'q' : 'Promise' + }; + + var callback = { + success : function(data) { + log.insertAdjacentHTML('beforeend', '1 success
'); + console.log(1, 'success', JSON.parse(data)); + }, + error : function(data) { + log.insertAdjacentHTML('beforeend', '2 error
'); + console.log(2, 'error', JSON.parse(data)); + } + }; + // End B + + // Executes the method call + $http(mdnAPI) + .get(payload) + .then(callback.success) + .catch(callback.error); + + // Executes the method call but an alternative way (1) to handle Promise Reject case + $http(mdnAPI) + .get(payload) + .then(callback.success, callback.error); + + // Executes the method call but an alternative way (2) to handle Promise Reject case + $http(mdnAPI) + .get(payload) + .then(callback.success) + .then(undefined, callback.error); + } + + if ('Promise' in window) { + var btn = document.getElementById('xhr'); + btn.addEventListener('click', testPromise); + } + else { + log.innerHTML = 'Live example not available as your browser does not support the Promise interface.'; + } + +}()); -- 2.1.4