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!