анализ исходного кода axios - процесс запроса

Node.js внешний интерфейс исходный код JavaScript axios

Мы не будем здесь представлять Axios, мы сразу перейдем к теме и проанализируем исходный код из базового запроса на получение.

axios.get('/get?name=xmz')
    .then((response)=>{
        console.log('response', response)
    })
    .catch((error)=>{
        console.log('error', error)
    })

Давайте сначала посмотрим на объект axios. На данный момент я думаю, что это обычный объект. После загрузки файла axios его можно использовать напрямую, поэтому я иду прямо к файлу, чтобы найти его ~~~

оказатьсяaxios/lib/axios.jsЯ прямо увидел, где лежит var axios.

var axios = createInstance(defaults);

Независимо от значений по умолчанию, это объект по умолчанию, и вы можете увидеть метод createInstance при поиске.

function createInstance(defaultConfig){
    var context = new Axios(defaultConfig);
    //new Axios()这么说context 是一个对象了
    var instance = bind(Axios.prototype.request, context);
    //bind()要对这个对象干什么???
    //...下面的就先不看了
    return instance;
}

Затем потяните дальнюю точку, чтобы увидеть метод привязки контекста, в конце концов, что делать? определение привязкиaxios/lib/helps/bind.jsв этом каталоге

function bind(fn, thisArg){
    return function wrap(){
        var args = new Array(arguments.length);
            for(var i = 0; i < args.length; i++){
                args[i] = arguments[i]
            }
            return fn.apply(thisArg, args)
        }
    }

bind возвращает перенос функции.Не глядя на слова внутри, мы можем знать, что экземпляр является функцией, а затем, когда экземпляр выполняется, он фактически выполняет Axios.proptotype.request, это указывает на контекст, грубо говоря, связывание чтобы изменить эту точку Ну, возврат функции createInstance — это экземпляр, поэтому axios — это экземпляр, который является функцией.

Поскольку axios — это функция, где определен атрибут get этой функции? Тогда я в целомaxios/libЯ просто и грубо искал axios.get в папке, но не нашел~~~ долго не мог найти! ! Сходить с ума! ! Но когда я пролистываю исходный код, я вижу, что в Axios.prototype есть атрибут get, но axios не является инстанцированным объектом Axios, что мне делать?

В это время обнаружилось, что после var axios у axios уже был атрибут get (написал for в цикле и тайно посмотрел на него), потом я проследил и нашел метод createInstance.

function createInstance(){
    //...
    //刚才有两行省略掉没看 好后悔!
    //看到extend 好激动
    utils.extend(instance, Axios.prototype, context);
    utils.extend(instance, context)
    return instance
}

Теперь я знаю, что свойство get axios изначально унаследовано от Axios.prototype, так что давайте посмотрим, как работает utils.entend! попал внутрьaxios/lib/util.jsдокумент.

function extend(a, b, thisArg){
    // extend就是把b的属性都复制个a
    forEach(b, function(value, key){
        //如果属性的值是一个方法的话,就改变this的指向到thisArg再复制给a 
        if(thisArg && typeof value == 'function'){
            a[key] = bind(val, thisArg)
        }else{
            a[key] = value;
        }
    })
    return a
}

axios наследует все атрибуты Axios.prototype и контекст, а значение свойства — это метод, то это точка, к которой относится контекст. На этот раз вы можете увидеть Axios.prototype.get и не искать, я вижу, что он не определен напрямую в файле! Хахаха! существуетaxios/lib/core/Axios.jsвнутри

utils.forEach(['delete', 'get', 'head', 'option'], function(method){
    Axios.proptotype[method] = function(url, config){
        // 先不去看util.merge了,我猜也就是把config 和 后面的对象进行下合并
        return this.request(util.merge(config||{}, {
            method: method,
            url: url
        }))
    }
})

Axios.prototype.get() на самом деле выполняет Axios.prototype.request(), который все еще находится в этом файле, посмотрите

Axios.prototype.request = function request(config){
    // ...
    // 开始就对config进行判断,合并默认配置
    var chain = [dispatchRequest, undefined]
    // dispatchRequest是什么一会再说
    var promise = Promise.resolve(config)
    // Promise.resolve一个对象,promise就是一个立即resolve的Promise对象
    // ...
    // 关于interceptors拦截器的东西先不看了
    while(chain.length){
        promise = promise.then(chain.shift(), chain.shift())
    }

    return promise
} 

Возвращается обещание, которое соответствует axios.get('/get?name=xmz').then().catch(). Независимо от перехватчика, после этого цикла while фактически выполняется диспетчерский запрос (конфигурация), затем перейдите кaxios/lib/core/dispatchRequest.jsпосмотри

function dispatchRequest(config){
    // ...
    // 开始就对config的 baseUrl, data, headers进行处理  
    var adapter = config.adapter || defaults.adapter;
    // 这个adapter是什么?一路以来并没有关注啊?
    // 执行adapter是一个Promise对象,resolve的函数的参数还是response
    // adpater肯定是去发送请求了啊
    return adapter(config).then(function(response){
        // ...
        return response
    }, function(reason){
        // ...
        return Promise.reject(reason)
    })
}

Поскольку config.adapter его не видит, перейдите кaxios/lib/default.jsПосмотрите на defaults.adapter

var defaults.adapter = getDefaultAdapter();
function getDefaultAdapter(){
    var adapter;
    if(typeof XMLHttpRequest !== 'undefined'){
        // 浏览器环境
        adapter = require('./adapter/xhr');
    }else if(typeof process !== 'undefined'){
        // node环境
        adapter = require('./adapter/http');
    }
    return adapter;
}

Адаптер должен различать браузер и среду узла, тогда мы идемaxios/lib/adapter/xhr.jsДавайте взглянем на среду браузера, то есть она инкапсулирует обещание сделать сервер запросов ajax, поэтому я не буду его здесь рассматривать.

Давайте вернемся и посмотрим на запрос на получение в начале.Axios.get наследуется от Axios.prototype.get.На самом деле он выполняет Axios.prototype.request и возвращает объект обещания, так что вы можете использовать then и catch для получения возвращаемое значение и обработка ошибок. Основной функцией для выполнения ajax-запросов является адаптер, который различает браузер и среду узла.

Что ж, если не обращать внимания на различные детали, весь процесс вполне ясен!

Xiaobai впервые анализирует исходный код, с этим можно обойтись!

Что касается анализа перехватчиков,Портал, нажмите здесь.

Анализ запросов на отмену,Портал, нажмите здесь.