can-observation
Create observable values that derive their value from other observable values.
    new Observation( fn [, context][, options] )
  
  Creates an observable value from the return value of the given function called with this as the context.
The following creates a fullName observation that derives its values from
the person observable.
import Observation from "can-observation";
import observe from "can-observe";
const person = observe( { first: "Ramiya", last: "Meyer" } );
const fullName = new Observation( function() {
    return person.first + " " + person.last;
} );
fullName.value; //-> "Ramiya Meyer";
fullName.on( function( newName ) {
    newName; //-> "Bodhi Meyer"
} );
person.first = "Bodhi";
Parameters
- fn {function}:The function whose value is being observed. 
- context {Object}:What thisshould be whenfnis called.
- options {Object}:An object that can configure the behavior of the observation with the following properties: - priority {Number}- The priority this observation will be updated within can-queues.
- isObservable {Boolean}- If reading this observable should call add.
 
- priority 
Use Cases
can-observation is used to derive values from other values without
having to explicitly bind.   This is used many places within CanJS:
- can-define gettersthat cache their value.
- can-stache's live binding.
Use
To use can-observation, import it and create an observation that
reads from other observables and returns a value.
The following creates a fullName observation that derives its values from
the person observable.
import Observation from "can-observation";
import observe from "can-observe";
const person = observe( { first: "Ramiya", last: "Meyer" } );
var fullName = new Observation(function fullName(){
    return person.first + " " + person.last;
});
fullName.value; //-> "Ramiya Meyer";
fullName.on( function( newName ) {
    newName; //-> "Bodhi Meyer"
} );
person.first = "Bodhi";
Use off to unbind.
Debugging
Naming Functions
Observations name themselves using the name of the
function passed to them. If you are using a can-observation directly, you should make sure the
function has a meaningful name.
This can be done by using function declarations like:
var fullName = new Observation(function fullName(){
    return person.first + " " + person.last;
});
Instead of:
var fullName = new Observation(function(){
    return person.first + " " + person.last;
});
You can also name functions as follows:
//!steal-remove-start
var fn = function(){ ... };
Object.defineProperty(fn, "name", {
    value: "some meaningful name",
});
//!steal-remove-end
can-queues
If you use can-queues to debug, it's likely you'll see something like:
NOTIFY running  : Observation<fullName>.onDependencyChange ▶ { ... }
DERIVE running  : Observation<fullName>.update ▶ { ... }
These tasks are when an observation noticed a dependency has changed and when it began to update
its value. If you expand the task object (▶ { ... }), you should be able to see
exactly which dependency caused the observation to update.
How it works
can-observation uses can-event-queue/value/value to implement its .on, .off methods and
call its internal .onBound and .onUnbound methods.
When bound for the first time, an observation calls its function between can-observation-recorder's
start and stop to see what dependencies have been
bound.  It then uses recorder-dependency-helpers.js to bind those dependencies to it's dependencyChange method.
When a dependency change happens, an observation adds its .update method to the derive can-queues.
When the .update happens, it repeats the process in the above paragraph, binding and unbind to whatever dependencies are
found with   start and stop.
How it works: can-observation and can-observation-recorder
covers how can-observation works.
 GitHub
GitHub Twitter
Twitter