跳至主要內容
手写reduce

MDN参考

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

语法

reduce(callbackFn)
reduce(callbackFn, initialValue)

yyshino大约 2 分钟FrontEndJS手写系列
手写call、apply、bind

手写call、apply、bind

总结

  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefinednull,则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且applycall是一次性传入参数,而bind可以分为多次传入
  • bind是返回绑定this之后的函数,applycall 则是立即执行

yyshino大约 2 分钟FrontEndJS手写系列
并发请求
    /**
     * 在某些场景下,页面的请求数可能会有很多,
     * 比如:抓取、分片上传等,如果我们需要等一个请求完成后,
     * 再发起下一个请求,是必效率会比较低。
     * 为了提升效率,我们可以同时发出多个请求,但数量又不能太多,
     * 如若某请求完成,剩余等待的请求继续补位执行,
     * 将请求的结果(不论成功或失败),按原有数组的顺序返回。
     */

    /**
     * 11-并发事件
     * @param {string[]} urls 请求地址数组
     * @param {number} max 最大并发数
     */
    function consurRequest(urls, max) {
        return new Promise((resolve,reject) => {
            // 判断传入urls长度,为空直接返回[]
            if(urls.length === 0){
                resolve([])
                return
            }

            const results = []
            let count = 0 // 标识请求的完成数量
            let index = 0 // 下一个请求

            // 发送请求
            async function request(){
                // 退出逻辑
                if(index === urls.length){
                    return
                }

                // 存储 index,保持后续请求结果数组与urls数组对应
                const i = index
                const url = urls[index]
                index++
                try {
                    const resp = await fetch(url)
                    // resp加入到 results中
                    results[i] = resp
                } catch (err) {
                    // err 加入到results
                    results[i] = err
                    console.log('err',err)
                } finally {
                    // 判断是否所以的请求都完成
                    count++
                    // if(count === urls.length){
                    if(count === urls.length){
                        resolve(results)
                        return
                    }
                    request()
                }
            }

            const times = Math.min(max,urls.length)
            let promiseList = []

            for(let i = 0; i < times; i++){
                promiseList.push(request())
            }

            Promise.race(promiseList).then(() => {
            }).catch((err) => {
                reject(err)
            })
        })
    }

yyshino大约 1 分钟FrontEndJS手写系列
手写Promise相关方法

Promise.all

特点:

  • Promise.all() 方法接收一个promise的iterable类型(MDN)
  • 只返回一个promise实例
  • 当传入的参数promise全部成功时,最后的结果才会成功(成功的结果是所有的promise的成功的结果组成的数组),只要有一个promise失败,all返回的实例就是一个失败的promise(失败的结果是传入的参数中的第一个失败的promise的结果)
let p1 = new Promise(resolve => {
    setTimeout(resolve, 200, 1)
});
let p2 = new Promise((resolve, reject) => reject(2));
let p3 = 3;
console.log(Promise.all([p1, p2, p3]));//all方法
let myAll = function(parr) {
    let result = [],//最后成功的结果
        count = 0,//累加器,与len比较判断是否全部成功了
        len = parr.length;
    return new Promise((resolve, reject) => {
        for (let p of parr) {// 依次测试传入的参数(转化为promise)是否是成功的
            Promise.resolve(p).then(res => {
                result[count] = res;// 成功就加入到结果中
                count++;// 累加器加一
                if (count == len) {// 如果相等,说明都成功了,可以走成功resolve
                    resolve(res);
                }
            }, err => {
            // 只要有一个失败了,直接走失败reject
                reject(err);
            })
        }
    })
}
console.log(myAll([p1, p2, p3]));

yyshino大约 3 分钟FrontEndJS手写系列