Use of Array.reduce() method

Use of Array.reduce() method

The reason is that when learning the serial and parallel writing methods of asynchronous functions, I found that the reduce method can simplify the writing method, and then I saw such a piece of code in a blog:

var array = [1, [2, [3, 4], 5], 6];
function flatten(array) {  
    return array.reduce(function (arr, item) {  
        return (Object.prototype.toString.call(item) === '[object Array]'
            ? Array.prototype.push.apply(arr, flatten(item))
            : arr.push(item)
            , arr);
    }, []);
}
console.log(flatten(array));

I found a lot of things I didn't understand, and it took a little time to finally understand:

  1. reduce(fn,initValue)Takes 2 parameters. The first is the iterator function, the function of which is to process each element in the array from left to right. The function has 4 parameters, namely accumulator, currentValue, currentIndex, array.
    accumulator The accumulator, the return value of the last call of the function.
    The first time is the value being processed by the function in the initialValue || arr[0]
    currentValue array.
    The first time the index array in the initialValue || arr[1]
    currentIndex array is being processed by the function . The second optional parameter of the array initValue called by the function is the initial value of the accumulator. If not, the first value of the accumulator is currentValue;

    reduce

  2. return (a,b)This is actually the comma operator. Calculate the left side first, then the right side, and finally return the value on the right. for example

    var n = (1,2,3,4);
    console.log(n); //4
  3. Then reducethe function of the first parameter must have a return value every time ;
  4. Array.prototype.push.apply(arr1,arr2)Why can you put 2 arrays concat()together.
    I think I should be able to figure it out. I've seen it before but I haven't used it much, and I'm not impressed, so I don't remember it.
    This starts with call, apply, and bind .
    The first parameter of fn.call() , the object to be passed in, the second and subsequent parameters are the parameters of fn, one-to-one correspondence;
    fn.apply() is the same as above, the second parameter becomes an array, the elements in the array One -to-one correspondence with the parameters of fn;
    fn.bind() is the same as apply , but call apply is executed directly. bind generates a new function and executes it when needed.
    This comes out, and Array.prototype.push.apply(arr1,arr2)pushes each element in arr2 as a parameter to arr1 insteadarr1.push(arr2) .

So the above means that the value of accumulator is the value of accumulator in the first iteration , and then flatten is called recursively, returning accumulator each time[]

  • In addition , apply has many clever uses, such as finding the maximum value of an array Math.max.apply(Math,arr);
  • Pseudo-array conversion Array.prototype.slice.apply(arguments)
    As mentioned above , it fn.apply()receives two parameters, one is the context and the other is the array as a parameter. At this time, only one context is passed ( argumentsit is a pseudo-array, there is no slice method, so the method on the array prototype is borrowed), and the slice itself does not pass parameters. If no parameters are passed, the default isslice(0) , that is, the Array.prototype.slice.apply(arguments,[0])entire array is copied and returned.

About promises

reduce can simplify the serial writing of promises ;.then()

//  promise生成函数
function log(n, delay, param) {
    return function () {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(n);
                resolve(param);
            }, delay);
        })
    }
}
/**异步函数的串行1
 * 这是正常的promise链式调用,每个then里面都返回一个promise;
 * 上一个执行完成,下一个才会执行
 */
Promise.resolve()
    .then(log(1,300))
    .then(log(2,0))
    .then(log(3,500))
    .then(log(4,100));

The above code prints out 1, 2, 3, 4 in order.
If you want to execute a function after 1, 2, 3, and 4 are all executed, you can use the Promise.all(arr)method to wrap multiple Promise instances into a new Promise instance. Specific examples are as follows:

//异步函数的并行写法
Promise.all([
    log(1, 300, "aa")(), log(2, 0, "bb")(), log(3, 1500, "cc")(), log(4, 100, "dd")()
]).then((result) => {
    console.log('finished!')
    console.log(result);
});
//2
//4
//1
//3
//finished!
//[ 'aa', 'bb', 'cc', 'dd' ]

If you want the serial writing method to be similar to this parallel writing method, you can use the reduce()function

//异步函数的串行2
//reduce中传入Promise.resolve()作为累加器的初始值
//第一次时Promise.resolve().then(fn)传入一个函数log(1, 300),函数运行后返回promis实例
//这个实例作为第二次的累加器的值,然后调用它的then()方法,并传入数组的第二项...
[log(1, 300),log(2, 0),log(3, 500),log(4, 100)].reduce((accumulator, value) => {
    return accumulator.then(value)
},Promise.resolve());

The result is the same as the above serial 1, print out 1, 2, 3, 4 in order

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325488131&siteId=291194637