1. Print red, yellow and green circularly
Let’s look at a typical problem, through which to compare several asynchronous programming methods: red 3s on once, green 1s on once, yellow 2s on once; How do I make three lights turn on again and again?
Three lighting functions:
function red() {
console.log('red');
}
function green() {
console.log('green');
}
function yellow() {
console.log('yellow');
}
Copy the code
The complexity of this problem lies in the fact that the light needs to be turned on “alternately and repeatedly” rather than “once”.
(1) Implement with callback
const task = (timer, light, callback) => {
setTimeout(() => {
if (light === 'red') {
red()
}
else if (light === 'green') {
green()
}
else if (light === 'yellow') {
yellow()
}
callback()
}, timer)
}
task(3000, 'red', () => {
task(2000, 'green', () => {
task(1000, 'yellow', Function.prototype)
})
})
Copy the code
There is a bug: the code only completes the flow once, and the red, yellow and green lights only shine once after execution. How do you make it alternate and repeat?
Recursion was mentioned above, and one cycle of light can be recursed:
const step = () => {
task(3000, 'red', () => {
task(2000, 'green', () => {
task(1000, 'yellow', step)
})
})
}
step()
Copy the code
Note that the yellow callback calls step again to complete the loop.
(2) Use promise to implement
const task = (timer, light) =>
new Promise((resolve, reject) => {
setTimeout(() => {
if (light === 'red') {
red()
}
else if (light === 'green') {
green()
}
else if (light === 'yellow') {
yellow()
}
resolve()
}, timer)
})
const step = () => {
task(3000, 'red')
.then(() => task(2000, 'green'))
.then(() => task(2100, 'yellow'))
.then(step)
}
step()
Copy the code
Here the callback is removed, and resolve the current promise after a light, still using recursion.
(3) With async/await implementation
const taskRunner = async () => {
await task(3000, 'red')
await task(2000, 'green')
await task(2100, 'yellow')
taskRunner()
}
taskRunner()
Copy the code
2. Print 1,2,3,4 every second
For (var I = 0; i < 5; i++) { (function(i) { setTimeout(function() { console.log(i); }, i * 1000); })(i); } // Use let block-level scope for (let I = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, i * 1000); }Copy the code
3. Children count questions
There are 30 children, numbered from 1 to 30, standing in a circle and counting off. The child who counts 1, 2 and 3 to 3 exits the circle. Then the next child counts 1, 2 and 3 again and asks what is the number of the last remaining child?
function childNum(num, count){ let allplayer = []; for(let i = 0; i < num; i++){ allplayer[i] = i + 1; } let exitCount = 0; // let counter = 0; // let curIndex = 0; While (exitCount < num - 1){if(allPlayer [curIndex]! == 0) counter++; if(counter == count){ allplayer[curIndex] = 0; counter = 0; exitCount++; } curIndex++; if(curIndex == num){ curIndex = 0 }; } for(i = 0; i < num; i++){ if(allplayer[i] ! == 0){ return allplayer[i] } } } childNum(30, 3)Copy the code
4. Use Promise to realize asynchronous loading of pictures
let imageAsync=(url)=>{ return new Promise((resolve,reject)=>{ let img = new Image(); img.src = url; Img. ο NL ο AD =()=>{console.log(' Picture request succeeded, general operation here '); resolve(image); } img.οnerrο R =(err)=>{console.log(' failed, failed general operation '); reject(err); }})} imageAsync (" url "). Then (() = > {the console. The log (" load success "); }). Catch ((error)=>{console.log(" load failed "); })Copy the code
5. Implement the publish-subscribe model
Handlers = {} // 2. AddEventListener (type, handler) {// Create a new array container if (! Handlers [type] = []; handlers[type] = []; handlers[type] = []; Event parameter dispatchEvent(type, params) {// An error is raised if (! Handlers [type]. Handlers [type]. ForEach (handlers => {handlers (... RemoveEventListener (type, handler) {if (! Handlers [type]) {return new Error(' invalid ')} if (! Handlers [type]} else {const index = this.handlers[type].findIndex(el => el === handler) Handlers [type]. Splice (index, 1) {return new Error(' no binding event ')} 1) if (this.handlers[type].length === 0) { delete this.handlers[type] } } } }Copy the code
6. Look for the most frequent words in the passage
Function findMostWord(article) {if (! article) return; Article = article.trim().tolowerCase (); let wordList = article.match(/[a-z]+/g), visited = [], maxNum = 0, maxWord = ""; article = " " + wordList.join(" ") + " "; ForEach (function(item) {if (visited. IndexOf (item) < 0) {// Join visited visited. Push (item); let word = new RegExp(" " + item + " ", "g"), num = article.match(word).length; if (num > maxNum) { maxNum = num; maxWord = item; }}}); return maxWord + " " + maxNum; }Copy the code
7. Encapsulate async fetch and use async await
(async () => { class HttpRequestUtil { async get(url) { const res = await fetch(url); const data = await res.json(); return data; } async post(url, data) { const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); const result = await res.json(); return result; } async put(url, data) { const res = await fetch(url, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(data) }); const result = await res.json(); return result; } async delete(url, data) { const res = await fetch(url, { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(data) }); const result = await res.json(); return result; } } const httpRequestUtil = new HttpRequestUtil(); const res = await httpRequestUtil.get('http://golderbrother.cn/'); console.log(res); }) ();Copy the code
Implement Prototype inheritance
The so-called stereotype chain inheritance is to make the stereotype of the new instance equal to the instance of the parent class:
Function SupperFunction(flag1){this.flag1 = flag1; } // SubFunction(flag2){this.flag2 = flag2; } // superInstance = new SupperFunction(true); // SubFunction. Prototype = superInstance; Var subInstance = new SubFunction(false); // The child calls its own and its parent's property subinstance.flag1; // true subInstance.flag2; // falseCopy the code
9. Implement bidirectional data binding
Let obj = {} let input = document.getelementById ('input') let span = document.getelementByid ('span') // data hijacking Object.defineProperty(obj, 'text', { configurable: true, enumerable: True, get() {console.log(' get data ')}, Set (newVal) {console.log(' data updated ') input.value = newVal sp.innerhtml = newVal}}) // Input listener input.addEventListener('keyup', function(e) { obj.text = e.target.value })Copy the code
10. Implement simple routes
// Hash Route class Route{constructor(){this.routes = {} // Hash this.currenthash = "// bind this, FreshRoute = this.freshRoute.bind(this) // Listen for window.addEventListener('load', this.freshRoute, 'load', this.freshRoute, ' False) window.adDeventListener ('hashchange', this.freshRoute, false)} Cb) {enclosing routes/path = cb | | function () {}} / / update freshRoute () {this. CurrentHash = location. Hash. Slice (1) | | '/' this.routes[this.currentHash]() } }Copy the code
Implement Fibonacci numbers
Function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const function fibonacci2(n) {const arr = [1, 1, 2]; const arrLen = arr.length; if (n <= arrLen) { return arr[n]; } for (let i = arrLen; i < n; i++) { arr.push(arr[i - 1] + arr[ i - 2]); } return arr[arr.length - 1]; } function fn(n) {let pre1 = 1; let pre2 = 1; let current = 2; if (n <= 2) { return current; } for (let i = 2; i < n; i++) { pre1 = pre2; pre2 = current; current = pre1 + pre2; } return current; }Copy the code
12. The maximum length of a string that cannot be repeated
Use a sliding window to install no duplicate characters, enumerating characters to record the maximum value. Use map to maintain the index of characters. When encountering the same character, move the left boundary across. Record the maximum length in the process of moving:
var lengthOfLongestSubstring = function (s) {
let map = new Map();
let i = -1
let res = 0
let n = s.length
for (let j = 0; j < n; j++) {
if (map.has(s[j])) {
i = Math.max(i, map.get(s[j]))
}
res = Math.max(res, j - i)
map.set(s[j], j)
}
return res
};
Copy the code
13. Use setTimeout to implement setInterval
SetInterval is used to execute a function at a specified interval, but it is not executed immediately. It is used to queue events at intervals, and only when the current stack is empty can it be removed from the event queue. Therefore, it may occur that the current execution stack is executed for a long time, resulting in the accumulation of multiple timer events in the event queue. When the execution stack ends, these events will be executed in sequence, so that the effect of the execution of a period of time cannot be achieved.
To address this shortcoming of setInterval, we can use a recursive call to setTimeout to simulate setInterval, so that we ensure that only one event ends before we fire the next timer event, which solves the setInterval problem.
The idea is to use recursive functions to continuously execute setTimeout to achieve the effect of setInterval
Function mySetInterval(fn, timeout) {var timer = {flag: true}; // Set the recursive function to simulate timer execution. function interval() { if (timer.flag) { fn(); setTimeout(interval, timeout); } // Start the timer setTimeout(interval, timeout); // Return timer; }Copy the code
14. The json
Function addScript(SRC) {const script = document.createElement('script'); script.src = src; script.type = "text/javascript"; document.body.appendChild(script); } addScript("http://xxx.xxx.com/xxx.js?callback=handleRes"); Function handleRes(res) {console.log(res); // Set a global callback function to receive the result of the callback. } // The interface returns the data format handleRes({a: 1, b: 2});Copy the code
15. Determine whether the object has a circular reference
Converting circular structure to JSON: Converting circular structure to JSON: This is what happens when you serialize an object.
The following methods can be used to determine whether a circular reference already exists in an object:
const isCycleObject = (obj,parent) => {
const parentArr = parent || [obj];
for(let i in obj) {
if(typeof obj[i] === 'object') {
let flag = false;
parentArr.forEach((pObj) => {
if(pObj === obj[i]){
flag = true;
}
})
if(flag) return true;
flag = isCycleObject(obj[i],[...parentArr,obj[i]]);
if(flag) return true;
}
}
return false;
}
const a = 1;
const b = {a};
const c = {b};
const o = {d:{a:3},c}
o.c.b.aa = a;
console.log(isCycleObject(o)
Copy the code
Find the target value of an ordered two-dimensional array:
var findNumberIn2DArray = function(matrix, target) {
if (matrix == null || matrix.length == 0) {
return false;
}
let row = 0;
let column = matrix[0].length - 1;
while (row < matrix.length && column >= 0) {
if (matrix[row][column] == target) {
return true;
} else if (matrix[row][column] > target) {
column--;
} else {
row++;
}
}
return false;
};
Copy the code
Oblique printing of two-dimensional arrays:
Function printMatrix(arr){let m = arr.length, n = arr[0]. Length let res = [] k < n; k++) { for (let i = 0, j = k; i < m && j >= 0; i++, j--) { res.push(arr[i][j]); }} // Bottom right, from 1 to n-1 to print for (let k = 1; k < m; k++) { for (let i = k, j = n - 1; i < m && j >= 0; i++, j--) { res.push(arr[i][j]); } } return res }Copy the code
conclusion
- Praise attention does not get lost
- Finish these questions; If you are interested, you can get up at six o ‘clock to punch in and study hard together!