What is a higher order function?
What are callbacks used for?
Example: Duplicate Code without Callbacks
function sendMessageConsole(message) {
console.log(message);
}
function sendMessageAlert(message) {
// alert(message);
}
function sendMessageConfirm(message) {
return confirm(message);
}
sendMessageAlert("Lots of duplication");
Example: Refactor With Callbacks
// Make sendMessage a higher order function and return a callback function
function sendMessage(message, callback) {
return callback(message);
}
sendMessage("Message for console", console.log);
// sendMessage("Message for alert", alert);
// var answer = sendMessage("Are you sure??", confirm);
Example: Callbacks with Function Declarations
//higher order function: greet, callback function: formatter
function greet(name, formatter) {
return "Hello, " + formatter(name);
}
function upperCaseName(name) {
return name.toUpperCase();
}
greet("Tim", upperCaseName); //Hello, TIM
Example: Callbacks with Anonymous Function (more common)
function greet(name, formatter) {
return "Hello, " + formatter(name);
}
greet("Tim", function(name) {
return name.toUpperCase();
});
greet("Tim", function(name) {
return name + "!!!!!";
})
Example: Callback signature
function callback(curElement, curIndex, array){
//call implemented by caller of function
}
Example: Implemention of forEach
function myForEach(arr, callback){
for (var i=0;i<arr.length;i++){
callback(arr[i],i,arr);
}
}
function findIndex(arr, callback){
for (var i=0;i<arr.length;i++){
if (callback(arr[i],i,arr)){
return i;
}
}
return -1;
}
var langs = ["Java", "C++", "Javascript"];
findIndex(langs, function(lang, index, arr){
lang === "Javascript"; //missing return keyword
});
-An area in memory where the your data is stored
// The object is created in the heap. obj is a reference to the object.
var obj = {firstName: "Tim", lastName: "Garcia"};
// New data is not created, only a copy of the reference
var referenceCopy = obj;
setTimeout
setInterval
Example: setTimeout usage
function callback() {
console.log("callback function");
}
var delay = 1000; // Delay is in ms
setTimeout(callback, delay);
Example: Canceling setTimeout
//Output Console: Canceling the first setTimeout 42
var timerId = setTimeout(function() {
console.log("This function runs in 30 seconds");
}, 30000);
setTimeout(function() {
console.log("Canceling the first setTimeout", timerId);
clearTimeout(timerId);
}, 2000);
Example: setInterval usage
function callback() {
console.log("callback is called continuously");
}
var repeat = 3000;
setInterval(callback, repeat);
Example: Canceling setInterval
var num = 0;
var intervalId = setInterval(function() {
num++;
console.log("num:", num);
if (num === 3) {
clearInterval(intervalId);
}
}, 1000);
The Queue
The Event Loop
Queue Example:
JavaScript is Single Threaded
Example:
function square(n) {
return n * n;
}
setTimeout(function() {
console.log("Callback is placed on the queue");
}, 0);
console.log(square(2));
Example: Promise: With Randomly Occurring Errors
var p1 = new Promise(function(resolve, reject) {
var num = Math.random();
if (num < 0.5) {
resolve(num);
} else {
reject(num);
}
});
p1.then(function(result) {
console.log("Success:", result);
}).catch(function(error) {
console.log("Error:", error);
});
Example: Wrap setTimeout With Promise
Asynchronous Code: obj promise will be created before setTimeout is finished
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
var randomInt = Math.floor(Math.random() * 10);
resolve(randomInt);
}, 4000);
});
promise.then(function(data) {
console.log("Random int passed to resolve:", data);
});
Promises In Practice
Nested Callbacks
Example: Nested Async Callbacks (to be refactored)
var counter = 0;
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
setTimeout(function() {
counter++;
console.log("Counter:", counter);
}, 3000);
}, 2000);
}, 1000);
Example: Refactor
Step 1: Create a Function Declaration
var counter = 0;
function incCounter() {
counter++;
console.log("Counter:", counter);
}
Step 2: Create a runLater Function
function runLater(callback, timeInMs) {
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
var res = callback();
resolve(res);
}, timeInMs);
});
return p;
}
Step 3: Chain Promises
runLater(incCounter, 1000).then(function() {
return runLater(incCounter, 2000);
}).then(function() {
return runLater(incCounter, 3000);
}).then(function() {
// final .then not necessary
});