A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending. Promise users can attach callbacks to handle the fulfilled value or the reason for rejection.
A promise is an object which can be returned synchronously from an asynchronous function. It will be in one of 3 possible states:
Fulfilled: onFulfilled() will be called (e.g., resolve() was called)
Rejected: onRejected() will be called (e.g., reject() was called)
Pending: not yet fulfilled or rejected
Refer below for example
Template for promise in javascript
var promise = new Promise(function(resolve, reject) {
// do a thing, possibly async, then…
if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
Example of Promise usage
//API definition
fetch_api: function(apicall){
return new Promise((resolve, reject) => {
if(this.serverList.length === 0)
reject("No floSight server working")
else{
fetch(this.serverList[this.curPos] + apicall).then(response => {
if(response.ok)
response.json().then(data => resolve(data));
else{
this.fetch_retry(apicall)
.then(result => resolve(result))
.catch(error => reject(error));
}
}).catch(error => {
this.fetch_retry(apicall)
.then(result => resolve(result))
.catch(error => reject(error));
})
}
})
}
},
// Call of this API
//Promised function to get data from API
promisedAPI: function (apicall) {
return new Promise((resolve, reject) => {
console.log(apicall)
this.util.fetch_api(apicall)
.then(result => resolve(result))
.catch(error => reject(error));
});
},
Promise Chaining
Because .then() always returns a new promise, it’s possible to chain promises with precise control over how and where errors are handled. Promises allow you to mimic normal synchronous code’s try/catchbehavior.
Like synchronous code, chaining will result in a sequence that runs in serial. In other words, you can do:
fetch(url).then(process).then(save).catch(handleErrors);
Please refer https://github.com/krdpk17/javascript-tutorial/blob/master/promise_dependency.html for example code for the same.
Ref: https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261
https://developers.google.com/web/fundamentals/primers/promises
Reactor Pattern in JavaScript
The Reactor Pattern is a way to achieve a reactive-programming style of coding with the use of a primitive called a Reactor.
One way to look at the reactor pattern is to consider it closely related to the idea of "non-blocking" operations. The reactor sends out notifications when certain operations can be completed without blocking. For example, select(2) can be used to implement the reactor pattern for reading from and writing to sockets using the standard BSD socket APIs (recv(2), send(2), etc). select will tell you when you can receive bytes from a socket instantly - because the bytes are present in the kernel receiver buffer for that socket, for example.
Reactor example
<script id="init_lib">
//All util libraries required for Standard operations (DO NOT EDIT ANY)
/* Reactor Event handling */
if (typeof reactor == "undefined" || !reactor) {
(function () {
function Event(name) {
this.name = name;
this.callbacks = [];
}
Event.prototype.registerCallback = function (callback) {
this.callbacks.push(callback);
};
function Reactor() {
this.events = {};
}
Reactor.prototype.registerEvent = function (eventName) {
var event = new Event(eventName);
this.events[eventName] = event;
};
Reactor.prototype.dispatchEvent = function (eventName, eventArgs) {
this.events[eventName].callbacks.forEach(function (callback) {
callback(eventArgs);
});
};
Reactor.prototype.addEventListener = function (eventName, callback) {
this.events[eventName].registerCallback(callback);
};
window.reactor = new Reactor();
})();
}
/* Sample Usage
--Creating and defining the event--
reactor.registerEvent('<eventName>');
reactor.addEventListener('<eventName>', function(someObject){
do something...
});
--Firing the event--
reactor.dispatchEvent('<eventName>',<someObject>);
*/
</script>
Example:
reactor.registerEvent("startUpSuccessLog");
reactor.addEventListener("startUpSuccessLog", log => console.log(log))
reactor.registerEvent("startUpErrorLog");
reactor.addEventListener("startUpErrorLog", log => console.error(log))
....
callStartUpFunction: function(fname){
return new Promise((resolve, reject) => {
this.startUpFunctions[fname]().then(result => {
this.callStartUpFunction.completed += 1
reactor.dispatchEvent("startUpSuccessLog",`${result}\nCompleted ${this.callStartUpFunction.completed}/${this.callStartUpFunction.total} Startup functions`)
resolve(true)
}).catch(error => {
this.callStartUpFunction.failed += 1
reactor.dispatchEvent("startUpErrorLog",`${error}\nFailed ${this.callStartUpFunction.failed}/${this.callStartUpFunction.total} Startup functions`)
reject(false)
})
})
},
Refer https://gist.github.com/mohsen1/5123533
Promise.all
Example for multiple promises in a single promise
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
// expected output: Array [3, 42, "foo"]
Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
The window object is supported by all browsers. It represents the browser's window.
All global JavaScript objects, functions, and variables automatically become members of the window object.
Below are few examples.
window.innerHeight - the inner height of the browser window (in pixels)
window.innerWidth - the inner width of the browser window (in pixels)
window.alert -> Method for popup alert
You can also add attribute to window object. Refer here
However, It is usually considered a bad practice to store variables into the window object.
Window localstorage
Create a localStorage name/value pair with name="lastname" and value="Smith", then retrieve the value of "lastname" and insert it into the element with id="result":
Refer below example
Example toast and get Smith value in local storage
<!DOCTYPE html>
<html>
<body>
<div id="result"></div>
<script>
// Check browser support
if (typeof(Storage) !== "undefined") {
// Store
localStorage.setItem("lastname", "Smith");
// Retrieve
document.getElementById("result").innerHTML = localStorage.getItem("lastname");
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Storage...";
}
</script>
</body>
</html>
Ref: https://www.w3schools.com/jsref/prop_win_localstorage.asp
window.IndexedDB
Its HTML5 feature. It is used to store data inside the browser.
IndexedDB is a built-in database, much more powerful than window.localStorage.
Key/value storage: value can be (almost) anything, multiple key types.
Supports transactions for reliability.
Supports key range queries, indexes.
Can store much more data than localStorage
Ref: https://javascript.info/indexeddb
Viewing indexedDB Database
Chrome devtools allows to look at this Database. You can delete database using this tool as well. Note that here test DB name is TEST_MODE
Ref: https://developers.google.com/web/tools/chrome-devtools/storage/indexeddb
For checking type of a object. Below example shows the chrome debugging console is used to provide (typeof reactor) output.
push method
It is used to push an item to the array
Ref: https://www.w3schools.com/jsref/jsref_push.asp
Please refer GitHub link https://github.com/krdpk17/Standard_Operations/blob/master/beginner-guide.md
Refer page https://developers.google.com/web/tools/chrome-devtools/javascript which explains about JS debugging using debugger
Look at below screenshot which depicts nice debugging support
Breakpoint is possible
Step by step code walkthrough is possible
Values of local variables are shown next to the variable
Log will output 10
for (var i = 0; i < 10; i++) { /* ... */ } console.log(i); // what will this output?
JavaScript makes it relatively easy to manipulate the DOM (i.e., add, modify, and remove elements), but does nothing to promote doing so efficiently.
While, admittedly, failing to use strict mode is not a “mistake” per se, its use is increasingly being encouraged and its omission is increasingly becoming considered bad form.
Here are some key benefits of strict mode:
Makes debugging easier. Code errors that would otherwise have been ignored or would have failed silently will now generate errors or throw exceptions, alerting you sooner to problems in your code and directing you more quickly to their source.
Prevents accidental globals. Without strict mode, assigning a value to an undeclared variable automatically creates a global variable with that name. This is one of the most common errors in JavaScript. In strict mode, attempting to do so throws an error.
Eliminates this coercion. Without strict mode, a reference to a this value of null or undefined is automatically coerced to the global. This can cause many headfakes and pull-out-your-hair kind of bugs. In strict mode, referencing a a this value of null or undefined throws an error.
Disallows duplicate property names or parameter values. Strict mode throws an error when it detects a duplicate named property in an object (e.g., var object = {foo: "bar", foo: "baz"};) or a duplicate named argument for a function (e.g., function foo(val1, val2, val1){}), thereby catching what is almost certainly a bug in your code that you might otherwise have wasted lots of time tracking down.
Makes eval() safer. There are some differences in the way eval() behaves in strict mode and in non-strict mode. Most significantly, in strict mode, variables and functions declared inside of an eval() statement are not created in the containing scope (they are created in the containing scope in non-strict mode, which can also be a common source of problems).
Throws error on invalid usage of delete. The delete operator (used to remove properties from objects) cannot be used on non-configurable properties of the object. Non-strict code will fail silently when an attempt is made to delete a non-configurable property, whereas strict mode will throw an error in such a case.
Q. My HTML page is huge. It has many Javascript code. Is it possible to refactor the Javascript as separate file and link to the html page
Ans: Yes. Please refer below example.
https://googlechrome.github.io/devtools-samples/debug-js/get-started
Reference
https://googlechrome.github.io/devtools-samples/debug-js/get-started
https://developers.google.com/web/tools/chrome-devtools/javascript
https://youtu.be/H0XScE08hy8
https://stackoverflow.com/questions/9138294/what-is-the-difference-between-event-driven-model-and-reactor-pattern
https://www.toptal.com/javascript/10-most-common-javascript-mistakes
https://www.geeksforgeeks.org/javascript-promises/