2024字节跳动春招技术面试题,源码拾遗系列之Axios,最新BAT大厂面试者整理的前端面试题目

);

var adapter = config.adapter || defaults.adapter;

return adapter(config).then(function onAdapterResolution(response) {

throwIfCancellationRequested(config);

// Transform response data

response.data = transformData(

response.data,

response.headers,

config.transformResponse

);

return response;

}, function onAdapterRejection(reason) {

if (!isCancel(reason)) {

throwIfCancellationRequested(config);

// Transform response data

if (reason && reason.response) {

reason.response.data = transformData(

reason.response.data,

reason.response.headers,

config.transformResponse

);

}

}

return Promise.reject(reason);

});

};

这里的 throwIfCancellationRequested 方法用于取消请求,关于取消请求稍后我们再讨论,可以看到发送请求是通过调用适配器实现的,在调用前和调用后会对请求和响应数据进行转换。

转换通过 transformData 函数实现,它会遍历调用设置的转换函数,转换函数将 headers 作为第二个参数,所以我们可以根据 headers 中的信息来执行一些不同的转换操作,

// 源码 core/transformData.js

function transformData(data, headers, fns) {

utils.forEach(fns, function transform(fn) {

data = fn(data, headers);

});

return data;

};

Axios 也提供了两个默认的转换函数,用于对请求和响应数据进行转换。默认情况下,

Axios 会对请求传入的 data 做一些处理,比如请求数据如果是对象,会序列化为 JSON 字符串,响应数据如果是 JSON 字符串,会尝试转换为 JavaScript 对象,这些都是非常实用的功能,

对应的转换器源码可以在 lib/default.js 的第 31 行找到,

var defaults = {

// Line 31

transformRequest: [function transformRequest(data, headers) {

normalizeHeaderName(headers, ‘Accept’);

normalizeHeaderName(headers, ‘Content-Type’);

if (utils.isFormData(data) ||

utils.isArrayBuffer(data) ||

utils.isBuffer(data) ||

utils.isStream(data) ||

utils.isFile(data) ||

utils.isBlob(data)

) {

return data;

}

if (utils.isArrayBufferView(data)) {

return data.buffer;

}

if (utils.isURLSearchParams(data)) {

setContentTypeIfUnset(headers, ‘application/x-www-form-urlencoded;charset=utf-8’);

return data.toString();

}

if (utils.isObject(data)) {

setContentTypeIfUnset(headers, ‘application/json;charset=utf-8’);

return JSON.stringify(data);

}

return data;

}],

transformResponse: [function transformResponse(data) {

var result = data;

if (utils.isString(result) && result.length) {

try {

result = JSON.parse(result);

} catch (e) { /* Ignore */ }

}

return result;

}],

}

我们说 Axios 是支持取消请求的,怎么个取消法呢?

CancelToken

其实不管是浏览器端的 xhr 或 Node.js 里 http 模块的 request 对象,都提供了 abort 方法用于取消请求,所以我们只需要在合适的时机调用 abort 就可以实现取消请求了。

那么,什么是合适的时机呢?控制权交给用户就合适了。所以这个合适的时机应该由用户决定,也就是说我们需要将取消请求的方法暴露出去,Axios 通过 CancelToken 实现取消请求,我们来一起看下它的姿势。

首先 Axios 提供了两种方式创建 cancel token,

const CancelToken = axios.CancelToken;

const source = CancelToken.source();

// 方式一,使用 CancelToken 实例提供的静态属性 source

axios.post(“/user/12345”, { name: “monch” }, { cancelToken: source.token });

source.cancel();

// 方式二,使用 CancelToken 构造函数自己实例化

let cancel;

axios.post(

“/user/12345”,

{ name: “monch” },

{

cancelToken: new CancelToken(function executor© {

cancel = c;

}),

}

);

cancel();

到底什么是 CancelToken?定位到源码 lib/cancel/CancelToken.js 第 11 行,

function CancelToken(executor) {

if (typeof executor !== “function”) {

throw new TypeError(“executor must be a function.”);

}

var resolvePromise;

this.promise = new Promise(function promiseExecutor(resolve) {

resolvePromise = resolve;

});

var token = this;

executor(function cancel(message) {

if (token.reason) {

// Cancellation has already been requested

return;

}

token.reason = new Cancel(message);

resolvePromise(token.reason);

});

}

CancelToken 就是一个由 promise 控制的极简的状态机,实例化时会在实例上挂载一个 promise,这个 promise 的 resolve 回调暴露给了外部方法 executor,这样一来,我们从外部调用这个 executor方法后就会得到一个状态变为 fulfilled 的 promise,那有了这个 promise 后我们如何取消请求呢?

是不是只要在请求时拿到这个 promise 实例,然后在 then 回调里取消请求就可以了?

定位到适配器的源码 lib/adapters/xhr.js 第 158 行,

if (config.cancelToken) {

// Handle cancellation

config.cancelToken.promise.then(function onCanceled(cancel) {

if (!request) {

return;

}

request.abort();

reject(cancel);

// Clean up request

request = null;

});

}

以及源码 lib/adaptors/http.js 第 291 行,

if (config.cancelToken) {

// Handle cancellation

config.cancelToken.promise.then(function onCanceled(cancel) {

if (req.aborted) return;

req.abort();

reject(cancel);

});

}

果然如此,在适配器里 CancelToken 实例的 promise 的 then 回调里调用了 xhr 或 http.request 的 abort 方法。试想一下,如果我们没有从外部调用取消 CancelToken 的方法,是不是意味着 resolve 回调不会执行,适配器里的 promise 的 then 回调也不会执行,就不会调用 abort 取消请求了。

更多关于源码学习:vue源码中值得学习的方法

小结

Axios 通过适配器的封装,使得它可以在保持同一套接口规范的前提下,同时用在浏览器和 node.js 中。源码中大量使用 Promise 和闭包等特性,实现了一系列的状态控制,其中对于拦截器,取消请求的实现体现了其极简的封装艺术,值得学习和借鉴。

参考链接

  • Axios Docs - axios-http.com[1]

  • Axios Github Source Code[2]

  • 源码拾遗 Axios —— 极简封装的艺术[3]

  • Cross Site Request Forgery - Part III. Web Application Security[4]

  • tc39/proposal-cancelable-promises[5]

❤️ 看完三件事

我是漫步,如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:

  • 点个【在看】,或者分享转发,让更多的人也能看到这篇内容

  • 关注公众号【前端开发博客】,不定期分享原创&精品技术文章。

  • 添加微信【 kujian89 】。加入前端开发博客公众号交流群。

21600470c33f9b10dc857f2297815296.png

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

学习笔记

主要内容包括html,css,html5,css3,JavaScript,正则表达式,函数,BOM,DOM,jQuery,AJAX,vue等等

HTML/CSS

CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

**HTML:**HTML基本结构,标签属性,事件属性,文本标签,多媒体标签,列表 / 表格 / 表单标签,其他语义化标签,网页结构,模块划分

**CSS:**CSS代码语法,CSS 放置位置,CSS的继承,选择器的种类/优先级,背景样式,字体样式,文本属性,基本样式,样式重置,盒模型样式,浮动float,定位position,浏览器默认样式

HTML5 /CSS3

**HTML5:**HTML5 的优势,HTML5 废弃元素,HTML5 新增元素,HTML5 表单相关元素和属性

**CSS3:**CSS3 新增选择器,CSS3 新增属性,新增变形动画属性,3D变形属性,CSS3 的过渡属性,CSS3 的动画属性,CSS3 新增多列属性,CSS3新增单位,弹性盒模型

JavaScript

**JavaScript:**JavaScript基础,JavaScript数据类型,算术运算,强制转换,赋值运算,关系运算,逻辑运算,三元运算,分支循环,switch,while,do-while,for,break,continue,数组,数组方法,二维数组,字符串

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

*JavaScript:**JavaScript基础,JavaScript数据类型,算术运算,强制转换,赋值运算,关系运算,逻辑运算,三元运算,分支循环,switch,while,do-while,for,break,continue,数组,数组方法,二维数组,字符串

[外链图片转存中…(img-jSzkfY29-1712238946184)]

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值