Don’t Repeat Yourself

JavaScript has been developed rapidly in past few years. Developers are able to accumulate experience through reduplicated work. However, in order to improve the work efficiency and code quality, it is suggested to organize and maintain your codebase in a elegant way - Write your own JS Library.

How

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(function(window){ /* function scope starts here */
'use strict';
function define_library(){
var LogDecorator = {}; // will be returned as a global variable
var logging = true; // disable/enable logging globally
var logPrefix = "----------------Start---------------------";
var logSuffix = "-----------------End---------------------";
LogDecorator.log = function(option, targetObj){
if(logging === true){
console.log(logPrefix);
console.log(`Option: ${option}`);
console.log('Target Object:');
console.log(targetObj);
console.log(logSuffix);
}
}
return LogDecorator;
}
//define globally if it doesn't already exist
if(typeof(LogDecorator) === 'undefined'){
window.LogDecorator = define_library();
}
else{
console.log("LogDecorator has already been defined.");
}
})(window); /* function scope ends */

Output Sample:

Test SampleTest Sample

Why

  1. Use Strict can eliminate silent errors by changing them to throw errors. Besides, Strict Mode can help JavaScript engines to perform optimizations. Refer to Strict mode for more details.

  2. Core Concept - JS Closures & Immediately-Invoked Function Expression

    Below is one way of using closures to define public functions that can access private functions and variables which is known as module pattern:

    1
    2
    3
    4
    5
    6
    (function() {
    // properties
    // methods
    // ...
    })(window);
    // Self-Executing Anonymous Functions

    () is the scope set for this function you are able to create private methods/functions and properties inside local scope. window inside () is used as global scope in browser environment.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // closures example
    var globalVar = 0;
    (function outerFunc(outerArg) {
    var outerVar = 3;
    (function innerFunc(innerArg) {
    var innerVar = 4;
    console.log(
    "outerArg = " + outerArg + "\n" +
    "innerArg = " + innerArg + "\n" +
    "outerVar = " + outerVar + "\n" +
    "innerVar = " + innerVar + "\n" +
    "globalVar = " + globalVar);
    })(2);
    })(1);
    // output:
    // outerArg = 1
    // innerArg = 2
    // outerVar = 3
    // innerVar = 4
    // globalVar = 0

Comment and share

Observer pattern (also known as Pub/Sub pattern) can be used to help break down a whole application into more loosely coupled modules.

There would be an object (observer collection) maintains a list of events. Those observers (subscriber) will be automatically notified once the event occurs.

Code Sample:

  1. observer subscribes to an event by the event name. ‘globalBroadcaster’ is an observer collection which stores the events subscribed. ‘handler’ is the action observer will make once the event occurs.

    1
    globalBroadcaster.subscribe('uniqueEventName', handler);
  2. Once the event be published, all the subscribers of this event will be notified. parameters could be injected when event published and it can be used by the subscribers. */

    1
    globalBroadcaster.publish('uniqueEventName', parameter1, parameter2, ...);
  3. Observer can unsubsribe the event in the ‘handler’ after being notified. In this case, observer won’t be notified if same event published again.

    1
    globalBroadcaster.unsubscribe('uniqueEventName', handler);

Conclusion

The biggest benifit of using Sub/Pub pattern comes from the concept of decoupling. Observer A doesn’t need to worry about how the event published or who announces the event, ‘A’ will process its handler once be notified.

The disadvantages also come from decoupling modules. It would be hard for one to draw a clearly workflow since some of the actions processed on the fly. It will cause chaos if not implemented properly.

Anyhow, I like the concept of decoupling, especially in group work.

Comment and share

JavaScript PromiseJavaScript Promise

JavaScript Promises are used to track the state of an asynchronous task.

1
new Promise(/* executor */ function(resolve, reject){...});

Promise states

  • fulfilled - the action relating to the promise successed
  • rejected - the action relating to the promise failed
  • pending - hasn’t fulfilled or rejected yet
  • settled - has fulfilled or rejected

A promise can be resolved to either a promise or thenable, in which case it will store the promise or thenable for later unwrapping.

how to create a promise

1
2
3
4
5
6
7
8
9
var promise = new Promise(function(resolve, reject){
//process a task, possibly async, then...
if(/* task successed */){
resolve("it worked!");
}
else{
reject(Error("it failed!"));
}
})

how to use promise

1
2
3
4
5
promise.then(function(result){
console.log(result); // "it worked!"
}, function(err){
console.log(err); //"it failed!"
});

then() takes two arguments, callback for a success case, and another for the failure case. Both are optional, so you are able to add a callback for the success or failure case only.

Resources:

Guide to JavaScript PromisePromise API Reference


Update (2017/06/11)

The purpose of async/await function is to simplify the behavior of using promises synchronously and to perform some behavior on a group of Promises. Just like Promises are similar to structured callbacks, async/await is similar to combining generators and promises. -MDN

Also read Why Async/Await is better than Promise

Comment and share

  • page 1 of 1
Author's picture

Zhao Cai

What will your verse be?


Web developer


Toronto