Skip to content

Instantly share code, notes, and snippets.

@jeremiahlangner
Last active January 23, 2019 21:36
Show Gist options
  • Save jeremiahlangner/0d77f9aa69b265d52ab327e5772d403e to your computer and use it in GitHub Desktop.
Save jeremiahlangner/0d77f9aa69b265d52ab327e5772d403e to your computer and use it in GitHub Desktop.
Sticky JS issues, often used in code interviews. Use, memorize, steal from at your leisure.
/**
*
* Instructions:
*
* Fix closure error in the following for loop so that, when clicked the button
* logs it's own number.
*
*/
(function() {
for(var i = 1; i <= 10; i++) {
var input = document.createElement('button');
input.innerHTML = 'button ' + i;
input.onclick = function(e) {
console.log(i);
}
document.querySelector('body').appendChild(input);
}
})();
/**
*
* Solutions: Each of these produces the desired result, though the first
* actually solves the "closure error."
*
*/
/* Using Closure */
(function() {
for(var i = 1; i <= 10; i++) {
(function(i) {
var input = document.createElement('button');
input.innerHTML = 'button ' + i;
input.onclick = function(e) {
console.log(i);
}
document.querySelector('body').appendChild(input);
})(i);
}
})();
/* Using ES6 limited variable scope */
(function() {
for(let i = 0; i < 10; i++) {
let input = document.createElement('button');
input.innerHTML = `button ${i}`;
input.onclick = function(e) {
console.log(i);
}
document.querySelector('body').appendChild(input);
}
})();
/* Calling external function with own closure; technically a "closure-based" solution */
(function() {
function createElement(i) {
var input = document.createElement('button');
input.innerHTML = 'button ' + i;
input.onclick = function(e) {
console.log(i);
}
document.querySelector('body').appendChild(input);
}
for(var i = 0; i < 10; i++) {
createElement(i);
}
})();
/* Spawning a function for each step. */
(function() {
for(var i = 0; i < 10; i++) {
function doThis(i) {
let input = document.createElement('button');
input.innerHTML = 'button ' + i;
input.onclick = function(e) {
console.log(i);
}
document.querySelector('body').appendChild(input);
}
doThis(i);
}
})();
/* Using forEach */
(function() {
for(var i = 0; i < 10; i++) {
var input = document.createElement('button');
input.innerHTML = 'button ' + i;
document.querySelector('body').appendChild(input);
}
let buttons = document.querySelectorAll('button');
[].forEach.call(buttons, function(button, i) {
button.onclick = function(e) {
console.log(i);
};
});
})();
/**
*
* Instructions:
*
* Merge two sorted arrays in as efficient manner as possible. arr1, and arr2.
*
*/
function mergeTwo(arr1, arr2) {
let merged = [];
let index1 = 0;
let index2 = 0;
let current = 0;
while (current < (arr1.length + arr2.length)) {
let isArr1Depleted = index1 >= arr1.length;
let isArr2Depleted = index2 >= arr2.length;
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1] < arr2[index2]))) {
merged[current] = arr1[index1];
index1++;
} else {
merged[current] = arr2[index2];
index2++;
}
current++;
}
return merged;
}
let result = mergeTwo(arr1, arr2);
<html>
<body>
<button id="add">+</button>
<span id="result">0</span>
<button id="subtract">-</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.3.3/rxjs.umd.min.js"></script>
<script>
/**
*
* Observables:
*
* Create a basic observable that increments or decrements a value based on
* user input.
*
*/
(function() {
const Rx = window['rxjs'];
console.log(window);
const addButton = document.getElementById('add');
const subtractButton = document.getElementById('subtract');
const resultDisplay = document.getElementById('result');
const addEvent = Rx.fromEvent(addButton, 'click');
const subtractEvent = Rx.fromEvent(subtractButton, 'click');
const add = addEvent.pipe(Rx.operators.map(e => e = 1));
const subtract = subtractEvent.pipe(Rx.operators.map(e => e = -1));
const source = Rx.merge(add, subtract);
var subscribe = source.subscribe(val => resultDisplay.innerHTML = parseInt(resultDisplay.innerHTML) + val);
})();
</script>
</body>
</html>
/**
*
* Promises:
*
* Instructions:
*
* The promise doesn't seem to return anything. Find the missing syntax
* and fix anything that's missing.
*
*/
(function() {
var promise = new Promise((resolve, reject) => {
var err;
if(err) {
reject(err);
}
var p = 'foo';
resolve(p);
});
})();
/**
*
* Solutions:
*
* Clearly the promise is never used.
*
*/
(function() {
var promise = new Promise((resolve, reject) => {
var err;
if(err) {
reject(err);
}
var p = 'foo';
resolve(p);
});
promise.then(function(p) {
console.log(p);
});
})();
/**
*
* Promise Libraries:
*
* Instructions:
*
* Execute a callback from a Promise for the requested option.
*
*/
(function() {
var promiseLib = {
resolvePromise: function() {
return new Promise((resolve, reject) => {
var err;
if(err) {
reject('there was an error');
}
function getRandomValue() {
var i = Math.round(Math.random());
if(i) {
resolve('two');
} else {
resolve('three');
}
}
getRandomValue();
})
},
on: function(req, cb) {
this.resolvePromise().then(function(res) {
if(req == res) {
cb(res);
}
});
}
};
promiseLib.on('two', function(res) {
console.log('response was ' + res);
});
promiseLib.on('three', function(res) {
console.log('response was ' + res);
});
})();
/**
*
* Instructions: Create an externally cancellable Promise.
*
*/
(function() {
function makePromise() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('There was a problem with the cancellation.');
}, 1000);
});
let cancel = new Promise((resolve, reject) => {
console.log(`I resolve on receiving input/an event from somewhere else.`);
window.addEventListener('PromiseCancellation', () => {
resolve('canceled');
});
});
Promise.race([promise, cancel]).then((result) => {
console.log(result);
});
}
function cancel() {
let cancel = new Event('PromiseCancellation');
window.dispatchEvent(cancel);
}
makePromise();
cancel();
})();
/* Using reject() instead of race() */
(function() {
function makePromise(cb) {
let promise = new Promise((resolve, reject) => {
let err;
if(err) {
reject('There was an error.');
}
window.addEventListener('PromiseCancellation', () => {
reject('Received a request to cancel the promise.');
});
setTimeout(() => {
resolve('There was a problem with the cancellation.');
}, 1000);
});
promise.then((res) => {
cb();
});
}
function cancel() {
let cancel = new Event('PromiseCancellation');
window.dispatchEvent(cancel);
}
makePromise();
cancel();
})();
/**
*
* Async/Await:
*
* Create a promise function that follows an async/await try/catch pattern.
*
*/
(function() {
function makePromise() {
return new Promise((resolve, reject) => {
let err;
if(err) {
reject(err);
}
resolve('This promise has been fulfilled.')
})
}
async function getPromiseResult() {
try {
const result = await makePromise();
console.log(result);
}
catch (err) {
console.log(err);
}
}
getPromiseResult();
})();
/* Async promise fulfillment in a loop. Resolve using promise.all. */
(function() {
function getAThing(thing) {
return new Promise((resolve, reject) => {
let thing = "something wonderful";
resolve(thing);
});
}
function retrieveThings(thingsArr) {
return new Promise((resolve, reject) => {
let promiseArr = [];
thingsArr.forEach(thing => {
let promise = getAThing(thing);
promiseArr.push(promise);
});
Promise.all(promiseArr).then((data) => {
resolve(data);
});
});
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment