分类
Promise

实现一个批量请求函数 multiRequest(urls, maxNum)

描述

要求最大并发数 maxNum,请求完成后返回结果。

代码

  function loadImg(url) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                const k = Math.random() * 10;
                if (k > 0.1) {
                    resolve(`${url}${k}`);
                } else {
                    reject('加载失败')
                }
            },20)
        })
    }
function multiRequest(urls, maxNum) {
        // 被分割的urls
        const gUrls = [];
        // 当前被分割的urls的下标
        let index = 0;
        // 若成功,返回的结果
        const result = [];
        // url分割
        for (let i = 0; i < urls.length; i+=maxNum) {
            gUrls.push(urls.slice(i, i+maxNum))
        }
        // 这是个Promise
        return new Promise((resolve,reject) => {
            // 执行函数
            const request = (resolve, reject) => {
                if (index < gUrls.length) {
                    const plist = [];
                    gUrls[index].forEach(item => {
                        plist.push(loadImg(item));
                    })
                    // 请求到之后
                    Promise.all(plist).then((res) => {
                        res.forEach(item => {
                            result.push(item);
                        })
                        index++;
                        // 放在Promise的then里,请求完这一次再执行
                        request(resolve, reject);
                    }).catch(e => {
                        // 失败就reject
                        reject(e);
                    });
                } else {
                    // 所有执行完成
                    resolve(result);
                }
            }
            // 开始执行
            request(resolve, reject);
        })
    }
    const urls=['1','2','3','1','2','3','1','2','3','1','2','3','1','2','3','1','2','3','1','2','3'];
    multiRequest(urls,4).then(res => {
        console.log(res);
    }).catch(err => {
        console.log(err)
    });

要点

  • 请求urls的分割。
  • 请求完这一波,再请求下一波。
  • 合并Promise。
  • Promise.all进行请求。
分类
Promise

实现Promise.retry

描述

实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject

代码

    // 定义
    Promise.retry = function(fn, num) {
        // 最终是返回一个Promise
        return new Promise((resolve, reject) => {
            // 执行函数
            let action = function (resolve, reject) {
                fn().then((prod) => {
                    resolve(prod);
                }).catch(e => {
                    if (num > 0) {
                        // 不为0递归调用执行函数
                        action(resolve,reject);
                    } else {
                        // 数量为0则拒绝
                        reject(e);
                    }
                    num--;
                })
            }
            // 调用执行函数
            action(resolve,reject);
        })
    }
    // 测试
    Promise.retry(() => {
        let num = Math.random()*10;
        return new Promise((resolve,reject) => {
            if (num > 5) {
                resolve(num);
            } else {
                reject('小于5');
            }
        })
    },5).then((prod) => {
        debugger;
    }).catch((err) => {
        debugger;
    })

要点

  • Promise.retry是有then的,所以返回new Promise。
  • 递归调用执行函数,若成功则返回,失败则继续调用,直至num归0。