The use of higher order functions

problem

Byte skipping: the original function, such as fetchData, is an asynchronous function, trying to get some information from the server and return a Promise. Writing a new function can automatically retry a certain number of times, and there is no difference between using it and the original function.

thinking

This question is not very difficult, but it may be the reason why the food is too tense. I didn't answer it very well at that time. However, the idea is very clear. The inner part counts by closures. Once the data is obtained successfully, it will return. Otherwise, it will continue to try until the number of retries reaches the upper limit.

function retry(fetch, n) {
    let i = 0
    function tryFetch(err) {
        if (i > n) {
            return "reach try limit:" + err
        } else {
            fetch().then(data => {
                return data
            }).catch(err => {
                i ++
                tryFetch(err)
            })
        }
    }
}

At that time, it was almost the same answer. There are several questions: the function call method is not the same as the original one. It should return a Promise according to the principle, more accurately, a function that returns a Promise. If there is any problem, you should be able to catch it outside. On the other hand, maybe the fetch function should take parameters and pass them in.

Solve

The modified function is as follows

function retry(fetch, n) {
    return function() {
        let args = arguments
        return new Promise((rseolve, reject) => {
            let i = 0
            tryFetch()
            function tryFetch(err) {
                console.log(i)
                if (i > n) {
                    reject("reach max try" + err)
                } else {
                    fetch(...args).then(data => {
                        rseolve(data)
                    }).catch(err => {
                        i ++
                        tryFetch(err)
                    })
                }
            }
        })
    }
}

Finally, I wrote a fetch to test

function fetch() {
    console.log(arguments)
    return new Promise((rseolve, reject) => {
        console.log('trying...')
        setTimeout(function() {
            if (Math.random() > 0.9) {
                console.log('resolved')
                rseolve('resolved')
            } else {
                console.log('rejected')
                reject('rejected')
            }
        }, 5000)
    })
}

The result is in line with the expectation and the problem is solved. Of course, you can also return to async function, but it is essentially the same idea as Promise.

Tags: Javascript

Posted on Tue, 03 Dec 2019 00:00:46 -0500 by sunilvadranapu