ecma6: Promise
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Thu, 27 Aug 2015 19:39:50 +0000 (21:39 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Thu, 27 Aug 2015 19:39:50 +0000 (21:39 +0200)
ecma6/.jscsrc [new file with mode: 0644]
ecma6/.jshintrc [new file with mode: 0644]
ecma6/promise/index.html [new file with mode: 0644]
ecma6/promise/promise.js [new file with mode: 0644]
ecma6/promise/promisexhr.js [new file with mode: 0644]

diff --git a/ecma6/.jscsrc b/ecma6/.jscsrc
new file mode 100644 (file)
index 0000000..be714a3
--- /dev/null
@@ -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 (file)
index 0000000..3a19927
--- /dev/null
@@ -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 (file)
index 0000000..802b2ee
--- /dev/null
@@ -0,0 +1,12 @@
+<html style="">
+  <head>
+  </head>
+  <body>
+    <button id="btn">Make a promise!</button>
+    <button id="xhr">Send XHR inside promise</button>
+      <div id="log">
+      </div>
+    <script src="promise.js"></script>
+    <script src="promisexhr.js"></script>
+  </body>
+</html>
diff --git a/ecma6/promise/promise.js b/ecma6/promise/promise.js
new file mode 100644 (file)
index 0000000..98dd475
--- /dev/null
@@ -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 (<small>Sync code started</small>)<br>');
+
+    // 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 (<small>Async code started</small>)<br>');
+        // 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 (<small>Async code terminated</small>)<br>');
+        return val;
+      })
+      .catch(
+      // Rejected promises are passed on by Promise.prototype.then(onFulfilled)
+      function(reason) {
+        log.insertAdjacentHTML('beforeend', 'Handle rejected promise 1 (' + reason + ') here <br>');
+        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 (<small>Async code terminated</small>)<br>');
+      })
+      .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 <br>');
+      }
+    );
+
+    log.insertAdjacentHTML('beforeend', thisPromiseCount +
+      ') Promise made (<small>Sync code terminated</small>)<br>');
+  }
+
+  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 <code>Promise</code> interface.';
+  }
+
+}());
diff --git a/ecma6/promise/promisexhr.js b/ecma6/promise/promisexhr.js
new file mode 100644 (file)
index 0000000..6d081ef
--- /dev/null
@@ -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 <br>');
+        console.log(1, 'success', JSON.parse(data));
+      },
+      error : function(data) {
+        log.insertAdjacentHTML('beforeend', '2 error <br>');
+        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 <code>Promise</code> interface.';
+  }
+
+}());