//

Sunday, September 15, 2019

Using deferred

Returning promises


Returning promises

If you are creating a long running function, you can return a promise, allowing the caller to be alerted to your operations status, or when it completes. You return, and manage, a promise by creating an instance Deferred.

Deferred

Deferred and promise seem very similar, and they are. The difference between the two is who uses which. Deferred is used to create, and manage, a promise object. A promise object is returned by a long running operation, and only allows you to register event handlers.
To put this another way, Deferred is the server side. When create a long running function that will be called by other developers, you'll use Deferred to return a promise. You'll use the Deferred object to update clients when your function completes (or you want to send a progress signal).
Continuing the analogy, promise is the client side. When you call a long running function, it will return a promise. You will use the promise to be alerted, and execute code, when that long running function completes (or sends a progress signal).

Using Deferred

When to use Deferred

If you are creating a function that may take a long time to execute, it's best to return a promise. This makes it easier for developers who call your function, as they can use the promise events.
One nice thing about jQuery is the developers of the API follow their own best practices. As a result, if you execute an operation, such as an Ajax call, the function will return a promise. If you are creating a function that will be wrapping such a call, you can simply return the promise returned by the function.
For example, consider the following jQuery. We create a function that calls slideToggleslideToggle can take a couple of seconds to execute, depending on how long you tell the operation to take. As a result, it returns a promise, as we saw in an earlier section. Because slideToggle returns a promise object already, we can just use that, rather than creating a Deferred object on our own.
function displayMenu() {
 // just return the promise object
 return $('#menu').slideToggle(500);
}
However, if we are creating a function that will take an unusual amount of time, say one that will be working with graphics, we need will want to use Deffered to return a promise to the caller.

Breaking down using Deferred

The basic steps are as follows.
  1. Create an instance of deferred: var deferred = $.Deferred();
  2. Start your asynchronous operation, typically using a worker
  3. Add the appropriate code to detect success and send the success signal: deferred.resolve()
  4. Add the appropriate code to detect failure and send the failure signal: deferred.reject()
  5. Return the promise: return deferred.promise();
function beginProcessing() {
 // Create deferred object & make sure it's going to be in scope
 var deferred = new $.Deferred();

 // Create our worker (just like before)
 var worker = new Worker('./Scripts/deferred.js');

 // Register the message event handler
 worker.addEventListener('message', function (e) {
  // simple messaging - if the worker is ready it'll send a message with READY as the text
  if (e.data === 'READY') {
   // No UI code
   // Progress notification
   deferred.notify('Worker started');
  } else if(e.data === 'COMPLETED') {
   // processing is done
   // No UI code
   // Completed notification
   deferred.resolve('Worker completed');

   worker.terminate();
  }
 });

 return deferred.promise();
}

Web workers

Introducing Web Workers

Introducing web workers

This section introduces the concept of HTML5 web workers. If you're already familiar with web workers, you're free to skip this section. If you're not already familiar with how web workers are implemented, or just want to brush up, this section is for you!

threading

Threading is a basic programming concept that allows developers to execute code on a separate process. Threading is extremely helpful when working with operations that either require additional processing power, or may take a long amount of time.
Applications typically start with a single thread that is used to execute code and update the user interface. If an operation is long running, and it executes on that thread, the user interface isn't able to be updated, and thus freezes. This provides a bad experience for the user. By using separate threads, you can execute your long running code elsewhere, allowing the user interface to still be responsive to the user.
As mentioned above, threading is an extremly powerful tool. Unfortunately, this tool can easily be mismanaged or abused, leading to degraded performance or potential security risks. This poses a challenge when working with web applications, in which users execute code (JavaScript) without knowing the developer of that code. Allowing threading in a browser could create an undesirable experience for the user. As a result, browsers don't allow JavaScript to use threads.
This is where web workers come into play.

Creating a web worker


Web workers

A web worker is made up of two components, the parent or calling script, and the worker or executing script. The worker runs in an environment similar to a separate thread, and does not have direct access to the calling environment or the UI. Web workers use a messaging system to pass information to and from the worker.

Creating the worker script

To create a web worker, you create a separate JavaScript file. This file will contain the code that will execute in the worker environment. The code in the file will execute immediately when the worker object is created from the calling script. As a result, if you wish to defer execution in a worker, the code will need to be contained inside of a function.

self

The web worker environment provdes an object named self, which represents the worker. self has one function and one event.
The worker provides a function named postMessage that is used to send data to the calling environment. postMessage accepts most data types, including JavaScript objects.
// send a signal back to the calling script
self.postMessage('hello from the worker!');
The worker offers one event, messagemessage is raised when the calling script has sent a message to the worker. message is raised when the calling environment calls postMessage, and thus almost any type of object can be received. The data passed into postMessage is available by using the data property of the event object.
// Receive a message from the calling environment
self.addEventListener('message', function(e) {
    // the data property will contain the data passed from the calling script
});

Calling a web worker


Calling a web worker

To call a web worker, you create an instance of the HTML5 Worker object. Because web workers are a relatively new development, it is a best practice to first check to see if the browser supports web workers. This can be done by testing if Worker is equal to null, meaning it doesn't exist. If Worker is null, you know the browser doesn't support web workers.
// Test if the browser supports web workers
if(Worker == null) {
 alert('You need to upgrade your browser!');
} else {
 // do your work here
}

Creating an instance of the Worker object

The constructor for Worker accepts one parameter, the location of the script it will load into the worker space. Remember, the script will execute immediately, so unless you're certain it's been built to allow you to start it manually, don't create the instance until the last possible momen.
var worker = new Worker('script-location.js');
Similar to what we've already seen, the worker object offers a postMessage method to send data to the worker space, and an event message that is raised when the worker sends a message back to the calling page. The parameter you pass to postMessage is retrieved by using the data property of the event object in the message event handler.
// Register event handler
worker.addEventListener('message', function(e) {
    $('#output').append('<li>' + e.data + '</li>');
});

worker.postMessage('Started!');

Web worker design practices


Designing your web workers

Creating a web worker that accepts status messages

As you may have noticed, the web worker doesn't provide a built-in structure for handling common events, such as start and finish. However, the worker's simple messaging system allows you to easily build your workers to perform the operations you need, and add your own system for managing start and stop events.
Quite frequently, you will want to delay execution of the worker script until the caller sends a signal to start. Remember, when your worker script is loaded, the script is run immediately. You can change this behavior by adding a simple check to the worker for a start message.
Because JavaScript is weekly typed, the data property of the event object passed by the workers doesn't need to be set in advance. You could set it to your status strings, such as START and STOP when you're sending those types of messages, and use a JavaScript object in data when you need to send other payloads.
The script below is one simple implementation of the behavior described, using simple strings for event management. You can use other objects as you see fit, depending on the complexity of your needs.
// worker.js

self.addEventListener('message', function(e) {
 if(e.data === 'START') {
  // Start message received.
  // Begin work
  startWork();
 } else if (e.data === 'STOP') {
  // Stop message received.
  // Perform cleanup and terminate
  stopWork();
 } else {
  // A different message has been received
  // This is data that needs to be acted upon
  processData(e.data);
 }
});

function startWork() {
 // code to start performing work here
 // send a message to the calling page
 // worker has started
 self.postMessage('STARTED');
}

function stopWork() {
 // cleanupp code here
 // stop the worker
 self.postMessage('STOPPED');
 self.close();
}

function processData(data) {
 // perform the work on the data
 self.postMessage('Processed ' + data);
}

Calling a web worker that accepts messages

One of the great advantages to having a worker that's been built to accept status messages, such as start and stop, is it makes it very easy to get everything set up, and then start the worker process when you're ready to have it run.
If you were using the worker that's been designed above, you would use it by following a couple of basic steps.
  1. Create an instance of Worker, passing in the script.
  2. Add the event handler for the message event. Ensure the event handler can respond to the status messages and normal data.
  3. When you're ready to start the worker's work, call postMessage('START');
  4. When you're done, send the stop message by calling postMessage('STOP');
// inside of HTML file

var worker = new Worker('worker.js');

worker.addEventListener('message', function(e) {
    if(e.data === 'STARTED') {
        // worker has been started
        // sample: update the screen to display worker started
        $('#output').append('<div>Worker started</div>');
    } else if(e.data === 'STOPPED') {
        // worker has been stopped
        // cleanup work (if needed)
        // sample: update the screen to display worker stopped
        $('#output').append('<div>Worker stopped</div>');
    } else {
        // Normal message. Act upon data as needed
        // Sample: display data on screen
        $('#output').append('<div>' + e.data + '</div>');
    }
});

// When you're ready, send the start message
worker.postMessage('START');

// Send data as needed
worker.postMessage('sample data');

// Stop worker when you're done
worker.postMessage('STOP');


Saturday, September 14, 2019

Using promises

Asynchronous concepts in jQuery


jQuery promises and deferred

Many operations you perform in both JavaScript and jQuery can take a non-deterministic amount of time.
Some operations, such as animations, take place over a specified amount of time. While you will frequently be responsible for specifiying the amount of time an amination will take, there will be times when the length of time will be variable.
Also, when creating rich web applications, you'll frequently access server resources from your scripts. When you add such functionality, you don't know how long the server is going to take to process your request and return a value.
When those types of operations take place, you don't necessarily care how long they're going to take, but you do need to execute code when they complete. This is where promises come into play.
promise is an object returned by functions in jQuery that take a long or variable amount of time. By using a promise, you can ensure your code executes whenever the operation completes, be notified of its success or failure, or potentially receive updates about an operation's progress.
Besides the built-in functions that return promises, jQuery also offers you a deferred object. A deferred object allows you to create your own long running operations, allowing developers to use the same patterns provided by the promise object, and be updated when your operation completes.
We're going to start our exploration of asynchronous programming in jQuery by introducing promises. We'll then see how you can create your own functions that return a promise through use of the deferred object. As part of this, we will also discuss the concept of a web worker, which is an HTML5 feature allowing web developers to simulate threads in a web browser.

Promises


jQuery promises

promise is a programming pattern in which a long running operation "promises" to let you know when it has completed its work.

Long running operations

Any jQuery function that runs over a long period of time, such as an animation, or communicates with a remote server, such as Ajax calls, returns a promise. The promise object offers several events that are raised when the operation is completed, or if there is a progress update.

Promise events


done

done is raised when the operation completes successfully.
done accepts one or more event handler functions.
The event handler can accept one or more parameters, which will contain whatever data the promise object has returned. For example, when making Ajax calls, you will be able to access the data returned by the server in the event handler's parameter. The data returned is determined by the operation.
// code to obtain promise object
promise.done(function(data) {
 // data will contain the data returned by the operation
});

fail

fail is raised when the operation has completed with an error.
Like donefail accepts one or more parameters. The parameters' values will be determined by the operation.
// code to obtain promise object
promise.fail(function(data) {
 // data will contain the data returned by the operation
});

progress

progress is raised when the operation raises an alert about its current state. Not all operations raise progress events.
Like done and failprogress allows you to specify one or more event handlers, each optionally accepting parameters. The parameter values are set by the operation.
// code to obtain promise object
promise.progress(function(data) {
 // data will contain the data returned by the operation
});

Chaining

You can add done and fail (and potentially progress) event handlers by chaining the method calls as demonstrated below.
// code to obtain promise object
promise.done(function(data) {
 // success
}).fail(function(data) {
 // failure
});

then

then is a single function allowing you to register donefail, and progress event handlers in one call. The sample below is identical to the chaining demonstration above.
// code to obtain promise object
promise.then(function(data) {
    // success
}, function(data) {
    // failure
});

Removing, replacing and cloning

Removing and replacing items

Removing and replacing items

Besides just creating new content, there will be times when you want to remove existing content, or replace content with new content. As you might have guessed, jQuery offers you this power as well.

remove and empty

Both remove and empty completely delete items from the DOM. The difference between the two is what they delete. In the case of remove, it will delete the item you target, while empty deletes the contents of the item you target.
Consider the following starting HTML
<div id="target">
    <div>Some cool content</div>
    <div>Some more cool content</div>
</div>
If you called $('#target').remove(), the resulting HTML would be, well, nothing. The entire contents of the sample are removed.
Contrast that with calling $('#target').empty()empty deletes the contents of the target, so the resulting HTML would be as follows
<div id="target">
</div>

replaceAll and replaceWith

If you wish to replace existing content with new content, jQuery offers replaceAll and replaceWith. In both cases, you'll provide what existing content you wish to replace, and what new content you wish to use. The difference between the two is the order in which you pass the existing and new content.
If you had the following starting HTML...
<div id="target">
    <div>Some cool content</div>
    <div>Some more cool content</div>
</div>
...and you wanted to finish with the following HTML...
<div>NEW content</div>
...then either method below would work.
// replaceWith replaces the content on the left with the new content in the parameter
$('#target').replaceWith('<div>NEW content</div>');

// replaceAll replaces the target in the parameter with the content on the left
$('<div>NEW content</div>').replaceAll('#target');
NOTE When using either replaceAll or replaceWith, the entire element is replaced, not just the contents of the element. Use both functions with caution.

Cloning

Clone

The main reason to use jQuery is because it makes "day to day" programming in JavaScript much easier, offering functionality and capabilities common to other programming environments. Because the basic operations become that much easier, it allows you to focus your attention on the cooler features you wish to add to your pages, adding interactivity, and making your page seem more like a locally installed application.
This is where the humble function clone comes into play. clone allows you to make a copy of jQuery objects.

clone in the real world

There are several scenarios in which clone simplifies content creation. Let's say you were building a page to allow an administrator to create email addresses and passwords. You'd like to ensure the administrator can create as many accounts as they would like on one page, and be able to send up all of the information to the server in one round trip, rather than using Ajax calls or submitting the form for each account.
This requires the ability to dynamically add labels and textboxes. You could do that this way
<button type="button" id="add-line">Add new line</button>
<div id="container">
 <div class="user-entry">
  <label>Email:</label>
  <input type="email" />
  <label>Password:</label>
  <input type="password" />
 </div>
</div>
$(function() {
 $('#add-line').click(function() {
  $('#container').append('<div class="user-entry"> <label>Email:</label> <input type="email" /> <label>Password:</label> <input type="password" /> </div>');
 });
});
It would work. But you've got a large string literal in JavaScript, which can be tough to debug when you got to make changes. In addition, whatever tool you're using to create your page isn't going to be able to offer you any support for the HTML that's inside of the string literal. And finally, we have the same markup twice, both in the starting HTML and in the JavaScript. (Granted, we could clean that up by adding the first line in through JavaScript, but that's not really the best solution here.)
A better way to solve this problem would be to clone the starting HTML that makes up the user information form, and then use that clone to add the new content. (The HTML below hasn't changed from above, it's copied for readability.)
<button type="button" id="add-line">Add new line</button>
<div id="container">
 <div class="user-entry">
  <label>Email:</label>
  <input type="email" />
  <label>Password:</label>
  <input type="password" />
 </div>
</div>
 $(function() {
  $userForm = $('.user-entry').clone;
 $('#add-line').click(function() {
  $('#container').append($userForm.clone());
 });
 });
Let's break down the code just a bit here. For starters, you'll notice on line 2 that we are grabbing a clone of the item with the class of user-entry. This contains the form for inputting the user. You'll also notice we use a variable that starts with $. This is common in jQuery to indicate the object is a jQuery object.
On line 4, you'll notice we use the $userForm in append to add the markup (or jQuery object) we copied earlier. What you'll also notice is we're calling clone() a second time. The reason for this is how JavaScript passes parameters. When you're working with an object, JavaScript passes a reference to the object, not a copy of the object. This would mean that we've added in a pointer to the clone we created earlier, not a brand new copy. The end result of this is if we called append a second time, we'd be trying to add the exact same object into the container again, not a brand new copy. By calling clone() again on line 4, we pass in a copy of our user form, rather than a pointer to the one we already used.
Below is a Pen with the code. You can use this to play around with the JavaScript, and see the impact removing clone has.

Combining cloning and animations

Cloning and animations

Now that we know how to clone items to simplify creation of dynamic content, and how to animate them to add some additional punch to our pages, let's see how we could bring it all together.
In the cloning section, we had the following demo HTML:
<button type="button" id="add-line">Add new line</button>
<div id="container">
  <div class="user-entry">
    <label>Email:</label>
    <input type="email" />
    <label>Password:</label>
    <input type="password" />
  </div>
</div>
and the following JavaScript:
 $(function() {
  $userForm = $('.user-entry').clone();
 $('#add-line').click(function() {
  $('#container').append($userForm.clone());
 });
 });
Let's modify our code to provide animation to the new elements. We'll start making sure our cloned item is hidden by using the css function. Because $userForm is a jQuery object, manipulate it just like any other jQuery object.
// Insert after line 2
$userForm.css('display', 'none');
When we call append, we know that the new item is going to be the last element in the container. We can access container's children by using children, and access the last one by calling last.
We also know that the item is hidden, because we set it to be hidden. If we call show, it will then display, with the animation. We can accomplish this by cloning it into a variable, adding the new variable, and then calling show on the new variable.
// Replace line 4
var newUserForm = $userForm.clone();
$('#container').append($newUserForm);
newUserForm.show(750);
Our final JavaScript becomes:
$(function() {
 $userForm = $('.user-entry').clone();
  $userForm.css('display', 'none');
 $('#add-line').click(function() {
    var newUserForm = $userForm.clone();
  $('#container').append($newUserForm);
    newUserForm.show(1000);
 });
});
You can play with the full result in the Pen below.

Effective Branching Strategies in Development Teams

Effective Branching Strategies in Development Teams Effective Branching Strategies in Developme...