Topic 010: Coding Questions in JS
var ghead = document.getElementsByTagName("h2");
for (i = 0; i < ghead.length; i++) {
var gh = ghead[i];
var ts = gh.id;
var ts1 = gh.textContent;
console.log(ts1);
console.log(ts);
//console.log(i);
}
setTimeout
for 2000 ms executes before another function scheduled for 1000 ms using async
/await
and Promises? Can you provide a different approach using async
/await
that doesn’t involve a separate wait
function?You can nest the setTimeout
functions to ensure the order:
function function2000ms(callback) {
setTimeout(() => {
console.log("This function is executed after 2000 ms");
callback();
}, 2000);
}
function function1000ms() {
setTimeout(() => {
console.log("This function is executed after 1000 ms");
}, 1000);
}
// Execute function2000ms and pass function1000ms as the callback
function2000ms(function1000ms);
You can use Promises to chain the execution:
function function2000ms() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("This function is executed after 2000 ms");
resolve();
}, 2000);
});
}
function function1000ms() {
return new Promise((resolve) => {
setTimeout(() => {
console.log("This function is executed after 1000 ms");
resolve();
}, 1000);
});
}
// Chain the Promises to control the order
function2000ms().then(function1000ms);
async
/await
The async
/await
syntax makes it even clearer and more readable:
function wait(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function executeFunctions() {
await wait(2000);
console.log("This function is executed after 2000 ms");
await wait(1000);
console.log("This function is executed after 1000 ms");
}
// Execute the async function
executeFunctions();
In this example:
wait
is a helper function that returns a Promise resolving after a specified number of milliseconds.executeFunctions
is an async
function that uses await
to pause execution until each wait
call completes.async
/await
with PromisesYou can create a utility function to handle setTimeout
with a Promise
and then use async
/await
to control the execution order.
// Utility function that returns a Promise resolving after the specified time
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function function2000ms() {
await delay(2000);
console.log("This function is executed after 2000 ms");
}
async function function1000ms() {
await delay(1000);
console.log("This function is executed after 1000 ms");
}
async function executeFunctions() {
await function2000ms(); // Wait for the function2000ms to complete
await function1000ms(); // Then wait for the function1000ms to complete
}
// Execute the async function
executeFunctions();
Utility Function delay
: This function returns a Promise that resolves after a specified number of milliseconds using setTimeout
.
Async Functions function2000ms
and function1000ms
: These are asynchronous functions that wait for the delay
to complete before executing their code.
Main Execution Function executeFunctions
: This function uses await
to ensure function2000ms
completes before starting function1000ms
.
// Input array
let array = [10, 20, 30, 20, 30, 20];
// Create an object to store the counts of each element
let counts = {};
// Iterate through the array
for (let i = 0; i < array.length; i++) {
let num = array[i];
// If the element is already in the object, increment its count
if (counts[num]) {
counts[num]++;
} else {
// If the element is not in the object, add it with a count of 1
counts[num] = 1;
}
}
// Output the counts
for (let num in counts) {
console.log(`Count of ${num} is ${counts[num]}`);
}
When you run this script, you should get the following output:
Count of 10 is 1
Count of 20 is 3
Count of 30 is 2
2nd Method :
function countOccurrences(array) {
return array.reduce((acc, element) => {
if (acc[element]) {
acc[element] += 1;
} else {
acc[element] = 1;
}
return acc;
}, {});
}
// Example usage:
const array = ["apple", "banana", "apple", "orange", "banana", "apple"];
const counts = countOccurrences(array);
console.log(counts);
// Output: { apple: 3, banana: 2, orange: 1 }
3rd Method :
function countOccurrences(array) {
return array.reduce((acc, element) => {
acc[element] = (acc[element] || 0) + 1;
return acc;
}, {});
}
// Example usage:
const array = ["apple", "banana", "apple", "orange", "banana", "apple"];
const counts = countOccurrences(array);
console.log(counts);
// Output: { apple: 3, banana: 2, orange: 1 }
Callback hell refers to the situation where you have multiple nested callbacks within asynchronous JavaScript code, leading to code that is hard to read, understand, and maintain. This typically occurs when you have asynchronous operations dependent on the results of other asynchronous operations, resulting in deeply nested callback functions.
Here’s an example of what callback hell might look like:
asyncOperation1((result1) => {
asyncOperation2(result1, (result2) => {
asyncOperation3(result2, (result3) => {
// More nested callbacks...
});
});
});
Asynchronous operations in JavaScript, like fetching data from a server, reading from a file, or waiting for a user interaction, often involve callbacks. When you have multiple asynchronous operations depending on each other, each requiring a callback, the code can become difficult to manage due to the deeply nested structure.
There are several solutions to mitigate callback hell:
function handleResult1(result1) {
asyncOperation2(result1, handleResult2);
}
function handleResult2(result2) {
asyncOperation3(result2, handleResult3);
}
asyncOperation1(handleResult1);
asyncOperation1()
.then((result1) => asyncOperation2(result1))
.then((result2) => asyncOperation3(result2))
.then((result3) => {
// Handle final result
})
.catch((error) => {
// Handle errors
});
async function fetchData() {
try {
const result1 = await asyncOperation1();
const result2 = await asyncOperation2(result1);
const result3 = await asyncOperation3(result2);
// Handle final result
} catch (error) {
// Handle errors
}
}
fetchData();
function runPromisesInSeries(promises) {
return promises.reduce((accumulator, currentPromise) => {
return accumulator.then(currentPromise);
}, Promise.resolve());
}
// Example usage:
// Dummy functions returning promises for demonstration
const promise1 = () =>
new Promise((resolve) => {
setTimeout(() => {
console.log("Promise 1 resolved");
resolve("Result 1");
}, 1000);
});
const promise2 = () =>
new Promise((resolve) => {
setTimeout(() => {
console.log("Promise 2 resolved");
resolve("Result 2");
}, 1000);
});
const promise3 = () =>
new Promise((resolve) => {
setTimeout(() => {
console.log("Promise 3 resolved");
resolve("Result 3");
}, 1000);
});
runPromisesInSeries([promise1, promise2, promise3]).then(() => {
console.log("All promises completed");
});
The Event Emitter will have the following methods:
on(event, listener)
: Registers a listener for a specific event.off(event, listener)
: Unregisters a listener for a specific event.emit(event, ...args)
: Emits an event, calling all registered listeners with the provided arguments.once(event, listener)
: Registers a listener for a specific event that will be called at most once.Here is the implementation of the Event Emitter in JavaScript:
class EventEmitter {
constructor() {
this.events = {};
}
// Registers a listener for a specific event
on(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
// Unregisters a listener for a specific event
off(event, listener) {
if (!this.events[event]) return;
this.events[event] = this.events[event].filter((l) => l !== listener);
}
// Emits an event, calling all registered listeners with the provided arguments
emit(event, ...args) {
if (!this.events[event]) return;
this.events[event].forEach((listener) => listener(...args));
}
// Registers a listener for a specific event that will be called at most once
once(event, listener) {
const onceListener = (...args) => {
listener(...args);
this.off(event, onceListener);
};
this.on(event, onceListener);
}
}
// Usage example
const emitter = new EventEmitter();
const onFoo = (message) => {
console.log("foo listener:", message);
};
emitter.on("foo", onFoo);
emitter.emit("foo", "Hello, World!"); // Outputs: foo listener: Hello, World!
emitter.off("foo", onFoo);
emitter.emit("foo", "This will not be logged"); // No output
emitter.once("bar", (message) => {
console.log("bar listener:", message);
});
emitter.emit("bar", "This will be logged once"); // Outputs: bar listener: This will be logged once
emitter.emit("bar", "This will not be logged"); // No output
events
object which will hold event names as keys and arrays of listener functions as values.on
Method: Adds a listener to the array of listeners for a specified event. If the event does not exist, it initializes it with an empty array first.off
Method: Removes a specific listener from the array of listeners for a specified event. If the event or the listener does not exist, it does nothing.emit
Method: Calls all the listeners registered for a specific event with the provided arguments.once
Method: Adds a listener that will be automatically removed after it is called once.1st Method :
let str = "I love paypal";
// Split the string into an array of characters
let arrChars = str.split("");
// Count the occurrence of each character
const arrCharOccurrence = arrChars.reduce((prev, char) => {
if (prev.hasOwnProperty(char)) {
prev[char] = prev[char] + 1;
} else {
prev[char] = 1;
}
return prev;
}, {});
console.log(arrCharOccurrence); //{ I: 1, ' ': 2, l: 2, o: 1, v: 1, e: 1, p: 2, a: 2, y: 1 }
// Deep opy the object
const copiedObject = JSON.parse(JSON.stringify(arrCharOccurrence));
// Remove spaces from the copied object
delete copiedObject[" "];
console.log(copiedObject); // { I: 1, l: 2, o: 1, v: 1, e: 1, p: 2, a: 2, y: 1 }
// Club string together (concatenate characters)
const concatenatedString = Object.keys(copiedObject).join("");
console.log(concatenatedString); // Output: "Ilovepay"
2nd Method :
function countOccurrencesAndModifyString(input) {
// Step 1: Count occurrences of each character
const charCount = {};
for (const char of input) {
if (charCount[char]) {
charCount[char]++;
} else {
charCount[char] = 1;
}
}
// Step 2: Remove space key from the object
const charCountCopy = { ...charCount };
delete charCountCopy[" "];
// Step 3: Combine the characters of the string, excluding spaces
const modifiedString = input.replace(/\s+/g, "");
return {
charCount: charCount,
modifiedString: modifiedString,
};
}
// Example usage:
const inputString = "I love paypal";
const result = countOccurrencesAndModifyString(inputString);
console.log("Character Count:", result.charCount);
console.log("Modified String:", result.modifiedString); // Should print "Ilovepaypal"
// For the expected output "ilovepay":
const lowercaseInput = inputString.toLowerCase();
const finalResult = countOccurrencesAndModifyString(lowercaseInput);
console.log("Character Count (Lowercase):", finalResult.charCount);
console.log("Modified String (Lowercase):", finalResult.modifiedString); // Should print "ilovepaypal"
for
, forEach
and hasOwnProperty
?Data :
const employees = {
Alice: {
code: "A3443",
department: "Sales",
},
Bob: {
code: "B34s43",
department: "Marketing",
},
Charlie: {
code: "C3444",
department: "HR",
},
David: {
code: "D34s44",
department: "Engineering",
},
Eva: {
code: "E3445",
department: "Sales",
},
Frank: {
code: "F34s45",
department: "Marketing",
},
Grace: {
code: "G3446",
department: "HR",
},
Hannah: {
code: "H34s46",
department: "Engineering",
},
};
1st Method :
const departments = {};
Object.entries(employees).forEach(([name, details]) => {
const { department } = details;
if (!departments.hasOwnProperty(department)) {
departments[department] = [];
}
departments[department].push(name);
});
console.log(departments);
2nd Method :
const departments = {};
for (const [name, details] of Object.entries(employees)) {
const { department } = details;
if (!departments[department]) {
departments[department] = [];
}
departments[department].push(name);
}
console.log(departments);
3rd Method :
function departMentWiseUsers(obj) {
const arrUsers = Object.entries(obj);
//console.log(JSON.stringify(Object.entries(obj)));
let department = {};
arrUsers.forEach((user, index) => {
// console.log(user[1]);
if (department.hasOwnProperty(user[1].department)) {
department[user[1].department].push(user[0]);
} else {
department[user[1].department] = [user[0]];
}
});
return department;
}
console.log(JSON.stringify(departMentWiseUsers(employees)));
Note : if in
Data the value is 1 level under(i.e., const employees = { "input" : {"name":...}} ) to access or pass that data use
employees.input
function test(num) {
const add = () => {
return num + 12;
};
return add;
}
const addition = test(23);
const addition1 = test(10);
const addition2 = test(14);
console.log(addition()); // Output: 35
console.log(addition1()); // Output: 22
console.log(addition2()); // Output: 26
function generateLink(langCode) {
const specialCases = {
"pt-BR": "br/pt",
"fr-CA": "ca/fr",
"fr-FR": "fr/fr",
"zh-CN": "cn/zh",
"zn-TW": "tw/zn",
cs: "cz/cs",
da: "dk/da",
es: "es/es",
et: "ee/et",
he: "il/he",
ja: "jp/ja",
ko: "kr/ko",
pt: "pt/pt",
sl: "si/sl",
sv: "se/sv",
uk: "ua/uk",
vi: "vn/vi",
};
// Handle the default case
let path;
if (specialCases.hasOwnProperty(langCode)) {
path = specialCases[langCode];
} else {
path = `${langCode}/${langCode}`;
}
// Return the complete URL
return `https://www.xyz.com/${path}/Home.page`;
}
// Test the function
const langCodes = [
"bg",
"ar",
"cs",
"da",
"de",
"et",
"fi",
"fr-CA",
"fr-FR",
"he",
"hu",
"it",
"ja",
"ko",
"lt",
"lv",
"no",
"pl",
"pt-BR",
"pt-PT",
"ro",
"ru",
"sk",
"sl",
"sv",
"th",
"tr",
"uk",
"vi",
"zh-CN",
"zn-TW",
];
langCodes.forEach((code) => {
console.log(`Lang code: ${code}, Link: ${generateLink(code)}`);
});
function nextUnlike() {
return document.querySelector('[data-testid="unlike"]');
}
function wait(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function removeAll() {
let count = 0;
let next = nextUnlike();
let waitTime = 3000; // Start with a shorter wait time of 3 seconds
while (next && count < 1200) {
try {
next.focus();
next.click();
console.log(`Unliked ${++count} tweets`);
await wait(waitTime); // Initial wait time of 3 seconds
next = nextUnlike();
// If no unlike button is found, scroll to load more
if (!next && count < 1200) {
window.scrollTo(0, document.body.scrollHeight);
await wait(5000); // Shorter wait for loading more tweets
next = nextUnlike();
}
} catch (error) {
console.error("An error occurred:", error);
waitTime = Math.min(waitTime * 2, 60000); // Exponentially increase wait time if an error occurs
console.log(`Rate limit hit? Increasing wait time to ${waitTime / 1000} seconds.`);
await wait(waitTime); // Wait before retrying
}
}
if (next) {
console.log("Finished early to prevent rate-limiting");
} else {
console.log("Finished, count =", count);
}
}
removeAll();