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

Node.js внешний интерфейс Promise axios

Две статьи были проанализированы до

В этой статье давайте проанализируем, как реализован запрос на отмену, начав с простого примера запроса на отмену:

var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/get?name=xmz', {
    cancelToken : source.token
}).then((response)=>{
    console.log('response', response)
}).catch((error)=>{
    if(axios.isCancel(error)){
        console.log('取消请求传递的消息', error.message)
    }else{
        console.log('error', error)
    }
})
// 取消请求
source.cancel('取消请求传递这条消息');

Это пример простого запроса на отмену, затем с начала axios.CancelToken перейдите кaxios/lib/axios.jsв файле.

axios.CancelToken = require('./cancel/CancelToken');

CancelToken находится без особых усилий, в примере мы вызываем исходный метод, затем переходим кaxios/lib/cancel/CancelToken.jsЧто этот исходный метод делает в файле?

CancelToken.source = function(){
    var cancel;
    var token = new CancelToken(function executor(c) {
        cancel = c
    })
    return {
        token : token,
        cancel : cancel
    }
}

Исходный метод очень простой, то есть он возвращает объект со свойствами token и cancel, но и token, и cancel получаются через конструктор CancelToken, затем ищем в этом файле и находим функцию CancelToken.

function CancelToken (executor){
    // ...
    // 判断executor是一个函数,不然就报错
    var resolvePromise;
    this.promise = new Promise(function(resolve){
        resolvePromise = resolve;
    })
    var token = this;
    // 以上token现在有一个promise属性,是一个未成功的promise对象;
    executor(function cancel(message){
        if(token.reason){
            return;
        }
        token.reason = new Cancel(message);
        resolvePromise(token.reason);
    })
    // 这个cancel函数就是 上面函数中的cancel,也就是source.cancel;
}

Теперь я знаю, что source.cancel – это функция, а source.token – инстанциированный объект. Пока что я знаю об этом. Продолжайте читать первый пример статьи. Следующим шагом является отправка запроса. Существует строка кода внизу, которая выполняет исходный код.

source.cancel — это функция, используемая для запуска запроса на отмену.

Оглядываясь назад, мы видим, что вышеприведенная функция отмены, отменяющая выполнение, добавляет к токену атрибут причины, поэтому давайте посмотрим, что такое атрибут причины, и посмотрим на конструктор Cancel вaxios/lib/cancel/Cancel.jsв файле

function Cancel(message){
    this.message = message
}

Отмена особенно проста для добавления свойства сообщения к созданному объекту, поэтому теперь token.reason — это объект со свойством сообщения.

Продолжайте возвращаться к функции отмены, выполняется функция resolvePromise, затем объект token.promise, обещание, которое не было изменено на успешное состояние, стало успешным, и передается объект token.reason.

Вкратце, функция ОТМЕНА предназначена для того, чтобы обещание состояния токена стало успешным;

Ну я вдруг обнаружил, что анализ прервался и стал успешным, как его отменить? Несмотря на то, что текущий код синхронизации был выполнен, запрос еще не был отправлен.Надо посмотреть функцию, которая отправляет запрос.Процесс отправки запроса был проанализирован в предыдущей статье.Портал, нажмите здесь.

Прежде чем разбирать запрос на отправку, рассмотрим первый пример, который немного отличается от наиболее распространенной отправки запроса на получение.Там больше объектов конфигурации.Атрибут cancelToken, значением которого является token, работает ли он?axios/lib/adapters/xhr.jsДавайте выясним (здесь перехвачена только часть про cancelToken).

// 在发送请求之前,验证了cancelToken,看来此处就是用来取消请求的;
if(config.cancelToken){
    // 具体是如何取消的,是在这个判断内定义的;
    config.cancelToken.promise.then(function(cancel){
        request.abort();
        reject(cancel);
        request = null;
    })
}
// 发送请求
request.send(requestData);

Посмотрите внимательно, это всего лишь функция then промиса, которая будет выполнена только после того, как состояние промиса станет успешным.Как мы только что проанализировали, отмена должна сделать состояние этого промиса успешным, поэтому, если оно выполняется, отмените запрошенная функция, затем она будет выполнена, отменит запрос на отправку и превратит обещание запроса на отправку в отклонение, которое фиксируется axiox.get().catch();

Процесс был ясен и, наконец, подведен итог:

Выполнение отмены должно сделать обещание токена успешным. Перед отправкой фактического запроса проверьте, не изменился ли статус token.promise. Если он изменился, отмените запрос. Это такая простая идея, чтобы отменить запрос.