乐趣区

关于javascript:axios源码之模拟实现axios发送请求

axios 外部运作流程大抵如下

axios 入口 -
->axios 构造函数 -
->interceptors 申请拦截器 -
->dispatchRequest 办法 -
->transformRequest 申请转换器 -
->adapter 适配器 -
->transformResponse 响应转换器 -
->interceptors 响应拦截器 

具体模仿实现 axios 应用 dispatchRequest 办法,以及 adapter 适配器发送一个异步申请的外围代码

    // 模仿 axios 发送申请
    //1、申明构造函数
    function Axios(config){this.config = config;}
    // 为 Axios 的原型对象增加 request 办法,axios(),axios.get() 等,外围就是调 axios.request() 办法
    Axios.prototype.request = function(config){
        // 创立一个 promise 对象
        let promise =  Promise.resolve(config);
        // 申明一个数组,保留 promise 的 then 办法的两个参数
        let chains = [dispatchRequest, undefined]; //undefined 作用是占位
        // 调用 then 办法,指定回调
        let result = promise.then(chains[0],chains[1]);
        // 返回 promise 的后果
        return result;
    }
    //2、dispatchRequest 函数
    function dispatchRequest(config){// 该函数的返回后果必须是一个 promise 对象
        // 调用适配器发送申请
        return xhrAdapter(config).then(response => {
            // 省略对响应后果进行转换解决
            return response;
        },error=>{throw error;})
    }
    //3、adapter 适配器
    function xhrAdapter(config){ // 该函数的返回值也是 promise
        return new Promise((resolve,reject)=>{
            // 不思考申请体的发送,创立一个异步申请
            let xhr = new XMLHttpRequest();
            xhr.open(config.method, config.url);
            xhr.send();
            // 绑定事件
            xhr.onreadystatechange = function(){if(xhr.readyState === 4) {if(xhr.status >= 200 && xhr.status < 300) {
                        resolve({
                            // 自定义返回数据
                            config: config, // 配置对象
                            data: xhr.response, // 响应体
                            headers: xhr.getAllResponseHeaders(),
                            request: xhr,// 申请对象
                            status: xhr.status,// 响应状态码
                            statusText: xhr.statusText // 响应状态字符串
                        })
                    } else {reject(new Error('申请失败状态码为'+xhr.status))
                    }
                }
            }
        })

    }
    // 测试创立 axios 函数
    let axios = Axios.prototype.request.bind(null)
    // 用 axios 发送申请
    axios({
        method:'GET',
        url:'http://localhost:3000/posts'
    }).then(res=>{console.log(res)
    })
    

退出移动版