查看原文
其他

被问到 Java 和 Go 的区别,懵了

编程导航 2023-07-23

The following article is from 面试鸭 Author 编程导航和鱼友们

大家好呀,今天继续给大家分享一些优质面试题,希望对正在求职的朋友有所帮助~

后端

题目一

Java 和 C++、Go 语言的区别,各自的优缺点?

官方解析

Java、C++ 和 Go 都是流行的编程语言,它们各自有着自己的特点和优缺点。

Java 是一种面向对象的编程语言,最初被设计用于开发嵌入式系统,现在已广泛应用于企业应用、Web 应用和移动应用开发等领域。Java 的优点包括:

  • **平台性强(跨平台)**:Java 虚拟机(JVM)可以在不同的操作系统上运行 Java 程序,使得开发者可以编写一次代码并在多个平台上运行;

  • 安全性高:Java 有很多安全特性,例如自动内存管理、类的访问权限控制、异常处理等,可以有效避免一些常见的安全漏洞;

  • 生态系统完备:Java 的生态系统非常完善,有很多成熟的框架和工具可以帮助开发者快速构建复杂的应用。C++ 是一种系统级编程语言,最初被设计用于操作系统和系统软件的开发,现在也广泛应用于游戏、图形图像处理、嵌入式系统等领域。C++ 的优点包括:

  • 性能高:C++ 是一种编译型语言,可以生成高效的机器代码,所以在处理大量数据和对计算效率有要求的应用场景下具有优势;

  • 控制能力强:C++ 具有非常高的控制能力,可以直接操作计算机的硬件和内存等资源;

  • 应用领域广泛:C++ 适用于开发大型系统、高性能应用和底层软件,如操作系统、数据库、游戏引擎等。Go 是一种开源的编程语言,由 Google 公司开发,被设计用于开发高并发、分布式系统。Go 的优点包括:

  • 并发能力强:Go 具有轻量级的线程(goroutine)和基于消息传递的通道(channel),可以方便地实现并发编程;

  • 内存管理高效:Go 的内存管理采用自动垃圾回收机制,使得开发者可以更加专注于业务逻辑;

  • 语言特性简单:Go 的语法简单易懂,代码易于阅读和维护,同时提供了丰富的标准库和工具支持。

不同的编程语言适用于不同的应用场景,开发者可以根据项目的需求、自己的经验和偏好选择合适的语言。

鱼友的精彩回答

一切总会归于平淡的回答

JAVA

  • 优点
    • 简单易学,代码可读性强
    • 跨平台,一次编写可以在多个操作系统上运行
    • 面向对象,支持继承、多态等特性
    • 丰富的类库,可以快速开发应用程序
    • 自动内存管理,减少了内存泄漏的可能性
  • 缺点:
    • 由于JVM的存在,运行速度相对较慢
    • 对于实时性要求较高的场景,Java的表现可能不如C++和Go

C++

  • 优点:
    • 速度快,适合编写需要高性能的应用程序
    • 应用广泛,特别是在游戏开发、操作系统和嵌入式系统开发方面
    • 灵活性高,可以直接访问硬件和内存
  • 缺点:
    • 学习难度较高,需要掌握指针、内存管理等底层知识
    • 容易出现内存泄漏和指针错误等问题
    • 编写代码过程中需要更多的手动管理,相比 Java 更容易出错

Go:

  • 优点:
    • 高并发,天生支持协程,能够轻松编写高效的并发程序
    • 简单易学,语法简洁,上手容易
    • 静态类型语言,可以避免一些潜在的运行时错误
    • 快速编译,可以快速构建和部署应用程序
  • 缺点:
    • 缺乏丰富的类库,与 Java 和 C++ 相比有些不足
    • 在一些性能要求极高的场景中可能不如 C++ 表现
    • 语言本身还比较年轻,相关生态和工具还需要进一步完善 使用场景:

JAVA

  • 适合开发企业级应用程序、后端服务等。

C++

  • 适合开发需要高性能和高可靠性的应用程序,特别是在游戏开发、操作系统和嵌入式系统开发方面。

GO

  • 适合开发高并发的后端服务、微服务、容器化应用程序等.

当然,每种语言都有其独特的优势和适用场景,具体应根据项目需求和开发团队的技术背景来选择合适的语言。

如果当面试官问你这个问题时,他们可能想要了解你对不同编程语言的了解和理解程度,以及你是否能够根据不同的项目需求和特点选择合适的编程语言。

此外,面试官可能还想知道你是否有跨语言的经验和能力,以及你是否能够评估和解决跨语言集成和兼容性问题。

最后,通过你的回答,面试官还可以了解你对软件开发生态系统的了解程度,以及你是否能够在行业发展和趋势方面保持敏锐的洞察力。

题目二

什么是 Redis?Redis 有哪些特点?Redis 有哪些常见的应用场景?

官方解析

Redis(Remote Dictionary Server)是一个开源的高性能键值存储系统,也被称为数据结构服务器。它支持多种类型的数据结构,如字符串、哈希、列表、集合、有序集合等,并提供了丰富的操作这些数据结构的命令。

Redis的特点包括:

  • 高性能:Redis使用内存来存储数据,并且数据存储在单一的进程中,因此速度非常快。

  • 多样的数据类型:Redis 支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等。

  • 持久化:Redis 支持多种持久化方式,包括 RDB 快照和 AOF 日志。

  • 分布式:Redis 支持分布式部署,可以将数据分布在多个节点上。


  • 简单易用:Redis 提供了丰富的命令,使得操作数据非常方便。


Redis 的常见应用场景包括:

  • 缓存:Redis 可以作为缓存使用,加速数据读取和响应速度。

  • 消息队列:Redis 提供了列表和发布/订阅功能,可以用来实现消息队列。

  • 计数器:Redis 的计数器功能非常高效,可以用来实现页面访问量、点击量等的计数。排行榜:Redis 的有序集合功能可以用来实现排行榜。分布式锁:Redis 可以用来实现分布式锁,保证多个进程之间的互斥访问。实时数据分析:Redis 可以作为实时数据分析的缓存层,加速数据分析速度。

总之,Redis 具有高性能、多样的数据类型、分布式、简单易用等特点,可以应用于各种场景,特别适合用来解决读写频繁的问题。

鱼友的精彩回答

Gianhing 的回答

Redis 是基于内存的键值型(key - value)的 NoSQL 数据库(非关系型数据库)。key 一般是 String 类型,而 value 支持丰富的数据类型,包括String、Hash、List、Set、SortedSet 这五种基本类型,此外还有 GEO、BitMap、HyperLogLog 等其他类型。

Redis 有哪些特点?

  • 读写性能优异

    • 基于内存,内存的访问速度是比磁盘快很多的
    • 采用单线程模型,不存在多线程的上下文切换,不需要考虑锁的问题
    • 使用 IO 多路复用模型,让 Redis 不需要创建额外的线程来监听客户端的大量请求,减少性能的消耗
    • 内置了多种优化过的数据结构实现
  • 所有操作命令都是原子性的

  • 支持事务

    • 允许多个命令按顺序执行并不会被打断
    • 不支持回滚
  • 支持数据持久化

    • RDB:通过创建快照来获得存储在内存里面的数据在某个时间点上的副本
    • AOF:执行完更改数据的命令后,会将该命令记录到日志中
  • 支持分布式部署

Redis 有哪些常见的应用场景?

  • 数据缓存

    • 将热点数据缓存到 Redis,提高数据读取和系统响应速度。
    • 将用户凭证(如 token)存入 Redis,实现单点登录。
  • 分布式锁

    • 利用 Redis 的 setnx 命令实现互斥,对于 setnx 命令,如果 key 不存在则会设置 key 的值并返回 1,否则直接返回 0。

    • 因此,可以通过 setnx 命令去尝试获取锁,获取锁成功才能继续执行相应业务。

    • 此外,还得给锁设置一个过期时间,防止系统出现问题导致锁无法释放。

使用命令为:

SET key value EX expire NX # 使用单命令保证设置指定 key 的值和过期时间是一个原子操作

如果需要更复杂的需求,可以采用 Redisson,它里面提供了多种分布式锁的实现。

  • 限时业务的运用

    • Redis 中可以使用 expire 命令设置一个键的生存时间,到时间后 Redis 会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。
  • 全局唯一 ID

    • Redis 由于 incrby 命令可以实现原子性的递增,所以可以用于唯一分布式序列号的生成。
  • 消息队列

    • 基于 List 实现:利用 LPUSH 和 RPOP;
    • 基于 PUB/SUB 实现;
    • 基于 Stream 实现。
  • 共同关注

    • 由于 Set 支持交集、并集、差集等功能,可以实现共同关注、共同爱好等功能。
  • 排行榜

    • 由于 SortedSet 是支持排序的,可以用于各种排行榜的场景。
  • 统计活跃用户

    • 利用 BitMap,以日期为 key,用户 ID 为 offset,当日活跃过就设置为 1。
  • 页面统计 UV

    • 将访问指定页面的每个用户 ID 添加到 HyperLogLog 中,调用 PFCOUNT 获取。

yes.的补充

因为我的项目中也有使用到Redis,在这里大胆猜测一下面试官会问到:在你的项目中是怎么使用Redis的?

  1. 在我的项目中使用 Redis 配合 Spring 的 redis-session,将用户的登录态存入 redis,实现单点登录。
  2. 对于系统的首页,为了加快响应速度,设置定时任务将首页数据缓存到 Redis中,避免了首页加载过慢用户体验差的情况。
  3. 对于用户加入队伍的限制,使用 Redisson 作分布式锁,防止了用户恶意请求加入超出限制数量的队伍。

题目三

简述计算机网络七层模型和各自的作用?

官方解析

计算机网络七层模型是一个把网络通信协议分为七个层次的标准模型,其目的是为了让计算机网络的设计和管理更加灵活和模块化。这个模型被称为OSI模型(Open System Interconnection Model),它由国际标准化组织(ISO)于1984年发布,是一个开放的标准模型。

每个层次都有自己的独立功能和责任,这种分层的方式使得每个层次都可以独立工作,同时还能够很好地协调上下层之间的数据传输,而不需要依赖于其他层次的实现细节。以下是每个层次的具体功能和责任:

  • 物理层:主要负责通过物理媒介传输比特流,如电缆、光纤、无线电波等。物理层规定了物理连接的规范,包括电缆的类型、接口的规范等。
  • 数据链路层:主要负责把数据分成数据帧进行传输,并对错误进行检测和纠正。数据链路层还负责物理地址的分配、数据流量控制、错误校验等。
  • 网络层:主要负责数据在网络中的传输,包括路由选择、分组转发、数据报文的封装等。网络层还处理数据包的寻址和控制流量等。
  • 传输层:主要负责数据传输的可靠性和流量控制等,同时还包括分段、组装、连接建立和断开等功能。传输层的最重要的两个协议是 TCP 和 UDP。
  • 会话层:主要负责建立、管理和终止会话,提供会话控制和同步等服务。会话层还负责处理多个应用程序之间的数据交换。
  • 表示层:主要负责数据格式转换、加密解密、压缩解压等服务。表示层使得应用程序可以使用不同的数据格式和编码,同时还提供了数据的安全性和完整性保护等服务。
  • 应用层:主要提供各种服务和应用程序,如电子邮件、文件传输、远程登录、Web 浏览等。应用层服务可以使用不同的协议实现,如 HTTP、SMTP、FTP、TELNET 等。OSI模型是一种理论模型,在实际应用中较少使用。现在比较常用的是TCP/IP模型,它只有四层:应用层、传输层、网络层和数据链路层。

鱼友的精彩回答

一切总会归于平淡的回答

当我们在浏览器中输入网址并访问一个网站时,首先经过物理层将电信号转换为比特流,再通过数据链路层将比特流转换为数据帧,通过 MAC 地址寻找到下一跳设备进行传输。在网络层中,通过 IP 地址寻找到目标主机,路由选择最优路径进行数据传输。在传输层中,通过 TCP 协议保证数据传输的可靠性,同时控制数据流量。在应用层中,通过 HTTP 协议实现浏览器和服务器之间的通信,完成网页的展示。

当面试官问到计算机网络七层模型及其各自的作用时,他很可能想要了解你对计算机网络的基础知识是否掌握,并且是否能够清晰地解释每个层次的功能和作用。

此外,他也可能希望了解你是否熟悉网络通信中的一些概念和术语,以及你是否能够在实际应用中使用这些知识来解决网络通信问题。

小熊佩萁的补充

OSI 七层模型 是国际标准化组织提出一个网络分层模型,其大体结构以及每一层提供的功能如下图所示:

每一层都专注做一件事情,并且每一层都需要使用下一层提供的功能比如传输层需要使用网络层提供的路由和寻址功能,这样传输层才知道把数据传输到哪里去

行云的补充

举例说明:用 QQ 聊天为例子

  • 用户在QQ界面输入文字,这就是应用层。
  • QQ 为了安全,要给文字加密,这就是表示层做的。
  • 会话层是找到对方的实体,也就是对方的 QQ 进程。
  • 传输层要找到对方的端口,就是 QQ 传输信息用的是哪个端口。
  • 网络层负责通过路由器要找到对方的网络地址。
  • 数据链路层要通过物理地址找到对方主机。
  • 物理层负责二进制比特流的传输。

前端

题目一

什么是 HTML5,HTML5 有哪些新特性?

官方解析

HTML5 是 HTML 的第五个版本,是用于创建网页和其他 web 应用程序的标记语言。与之前的 HTML 版本相比,HTML5 引入了许多新特性和改进,包括以下几个方面:

  • 语义化标签:HTML5引入了很多新的标签,如<header>、<footer>、<nav>、<article>、<section>等,这些标签都是为了更好地表达文档内容的语义而设计的。
  • 多媒体支持:HTML5 支持多媒体内容,包括音频、视频、SVG 和 Canvas 等图形元素,这些都可以直接在网页中嵌入,无需使用第三方插件。
  • 新的表单控件:HTML5 引入了一些新的表单控件,如日期选择器、搜索框、滑块等,这些控件都能够提高用户体验。
  • Web 存储:HTML5 提供了两种新的客户端存储机制:localStorage 和 sessionStorage,它们可以让 Web 应用程序在客户端上存储数据,从而提高性能和用户体验。
  • Web Workers:HTML5 提供了一种新的机制,即 Web Workers,它们可以让 Web 应用程序在后台运行,从而提高性能和响应速度。
  • 地理位置支持:HTML5 提供了一种新的 API,即 Geolocation API,它可以让 Web应用程序获取用户的地理位置信息。

HTML5的新特性为 Web 开发提供了更多的功能和工具,让开发者能够更加方便地开发 Web 应用程序,并提高用户体验。

鱼友的精彩回答

你还费解吗 的回答

HTML5 是 HTML 最新的标准,它比 HTML 更加规范,并添加了许多新的特性:

  • 语义化元素:即语义程度更强的 HTML 元素,能增强代码的可读性,使代码结构更加清晰,比如:
  • <header>:定义整个文档或文档某一部分的头部区域。
  • <nav>:定义文档的导航链接部分,仅对文档中关键的链接使用。
  • <article>:定义文档中的内容区域,且内容必须是独立于文档的其它部分。
  • <section>:定义文档的节,可对文档的某一部分进行分块或分段。
  • <aside>:定义与某个
    内容相关的额外内容区域。
  • <footer>:定义整个文档或文档某一部分的底部区域。
  • 表单元素:<datalist>、<keygen>、<output>
  • <input>的类型,如:
    • color:定义拾色器。
    • date:定义日期控件,包含年、月、日。
    • datetime:定义日期时间控件,包含年、月、日、时、分,基于 UTC 时区。
    • datetime-local:定义日期时间控件,包含年、月、日、时、分,无时区。
    • month:定义月份控件,包含月和年。
    • week:定义周控件,包含周和年。
  • <input>的属性,如:
    • required:规定当前输入域为必填项,当提交表单时会自动验证,若输入域为空则给出提示。
    • placeholder:用于设置当输入域为空时给出的提示信息。
    • autofocus:规定页面加载后,自动获取输入域的焦点。
    • autocomplete:是一个布尔值,若设置为true,则用户在输入时,浏览器会基于之前提交的值,显示出在字段中填写的选项。
    • form:指定输入域所属的表单。
  • 媒体元素:<video>(视频)和<audio>(音频)
  • 拖放:用于将某个对象拖放到另一个位置。
  • 地理定位:用于获取当前的位置。
  • Canvas:画布,通过 JavaScript 可以在画布中绘制各种图形。
  • SVG:可缩放矢量图形。
  • Web 存储:一种在浏览器本地存储数据的方法,通过两个全局对象实现:
    • sessionStorage(会话存储):当关闭浏览器窗口后,数据会被删除。
    • localStorage(本地存储):除非手动清除,否则数据将一直存在。
  • Web Socket:一种新的通信协议,允许服务端主动向客户端推送数据。

题目二

CSS 中的 1 像素问题是什么?有哪些解决方案?

官方解析

CSS 中的 1 像素问题指的是在高分辨率屏幕上显示的 1 像素边框或者细线在实际显示时会比 1 个物理像素更宽或更粗,从而导致边框或者细线看上去比预期的更粗或者更宽,影响页面的美观性和用户体验。

造成这个问题的原因是由于高分辨率屏幕的像素密度比传统的屏幕要高,所以在屏幕上显示的一个 CSS 像素对应的物理像素个数也会相应地增多,当使用 CSS 中的 1px 来设置边框或者细线时,实际上渲染出来的线条在屏幕上会被拆分为多个物理像素,从而导致看上去更粗。

解决这个问题的方法有以下几种:

  1. 使用图片代替边框或细线,这种方法能够保证显示效果的一致性,但是需要制作多张图片,增加了页面加载的开销。

  2. 使用 scale 进行缩放,使用 transform 缩放 0.5 像素大小的边框,以达到渲染 1 像素的效果。例如:

.border {
  position: relative;
  border: 1px solid #000;
}
.border:after {
  content: "";
  position: absolute;
  top: -1px;
  left: -1px;
  right: -1px;
  bottom: -1px;
  border: 1px solid #000;
  transform: scale(0.5);
}
  1. 使用 border-image,border-image 可以实现将一张图片作为边框样式,图片会自动拉伸或者重复以填充边框。这种方法需要制作一张边框的图片,但是可以通过 CSS 控制图片的填充方式和边框样式,比较灵活。例如:
.border {
  border: 1px solid transparent;
  border-image: url(border.png) 1 1 stretch;
}
  1. 使用 CSS3 的 box-shadow,可以用 box-shadow 属性来模拟边框。例如:
.border {
  box-shadow: 0 0 0 1px #000;
}

使用 viewport,在 head 中添加如下代码可以解决 1px 问题:

<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">

鱼友的精彩回答

一的回答

CSS 中的 1px 问题指的是,由于屏幕像素无法精确显示 1px,导致 1px 边框、阴影等在不同屏幕下显示效果不一致。这一问题困扰了无数 CSS 开发者,因为实现均匀、一致的 1px 效果对 UI 设计至关重要。

为了解决 1px 问题,CSS 开发社区总结了一系列解决方案:

  • 利用 GPU 加速绘制的特性,采用 outline、box-shadow 或 transform: scale(1); 来代替 border,从而获得更清晰的 1px 效果。
    • outline 与 border 类似但会触发 GPU 绘制
    • box-shadow 也会触发 GPU 绘制
    • transform: scale(1); 则会强制触发 GPU 绘制
  • 使用与屏幕大小相关的 viewport units(如 vw、vh 等)来代替固定的 px 单位。viewport units 会根据屏幕大小进行缩放,从而可以在不同屏幕下实现更平滑、自然的 1px 效果。
  • 简单地使用 2px 代替 1px,因为 2px 在大多数屏幕下都足够 thick,能以清晰、连续的形式显示。
  • 使用 border-image 来绘制复杂的 1px 边框,border-image 支持使用 SVG 路径绘制多段式或圆角边框,能在高像素密度屏幕下实现清晰的 1px 效果。
  • 采用 CSS 变量和 media queries 的组合来针对不同设备像素密度调整 1px 值。在 @media (min-resolution: 2dppx) { /* 设置较大值,如 2px */ } 中为高像素密度屏幕设置较大的 1px 值是一种比较优雅的解决方法。另外,确保采用 box-sizing: border-box; 以避免 border 和 padding 对元素宽度的影响,因为这会导致 1px 边框的模糊不清。

总之,通过灵活运用上述各种方法,我们可以在保证 UI 设计效果的前提下,巧妙地解决 CSS 中棘手的 1px 问题。

题目三

JavaScript 中如何中止网络请求?

官方解析

在 JavaScript 中,我们可以通过 AbortController 和 AbortSignal 来中止网络请求。

使用 AbortController 创建一个新的 AbortController 对象,然后使用它的 abort() 方法来中止请求。在创建请求时,将 AbortController.signal 分配给请求的 signal 属性,以便在调用 abort() 方法时取消请求。

以下是一个使用 AbortController 中止 fetch 请求的示例:

const controller = new AbortController();
const signal = controller.signal;

fetch(url, { signal }).then(response => {
  // Handle the response
}).catch(error => {
  if (error.name === 'AbortError') {
    console.log('Request was cancelled');
  } else {
    console.log('Request failed:', error);
  }
});

// To abort the request, call the following:
controller.abort();

在上面的示例中,我们通过调用 controller.abort() 方法来取消网络请求。

使用 AbortController 和 AbortSignal 是中止网络请求的一种可靠方式,并且在现代浏览器中得到了广泛支持。

鱼友的精彩回答

Stars的回答:

JavaScript中常用的网络请求方式为ajax(XMLHttpRequest实现),fetch、axios

以下为各种请求的终止方式

  1. xhrInstance.abort() 使用 XHR 对象中止请求,可以调用 abort() 方法。例如:
const xhr = new XMLHttpRequest()
xhr.open(method,url)
xhr.send()

// 然后在某个时间点调用 abort() 方法
xhr.abort();

当一个请求被终止,它的 readyState 将被置为 XMLHttpRequest.UNSENT (0),并且请求的 status 置为 0。

  1. AbortController.abort()
const controller = new AbortController();
const signal = controller.signal;

fetch('https://example.com/data', { signal })
  .then(response => {
  })
  .catch(error => {
  });

// 然后在某个时间点调用 abort() 方法
controller.abort();

abort() 方法会在 DOM 请求完成之前中止它。它能够中止 fetch 请求、各种响应主体或者流的消耗。

  1. CancelToken
const source = axios.CancelToken.source();

axios.get('/api/data', {
  cancelToken: source.token
}).then(response => {
  // 处理响应
}).catch(error => {
  if (axios.isCancel(error)) {
    console.log('请求已被取消:', error.message);
  } else {
    console.log('请求出错:', error.message);
  }
});

source.cancel('请求已被用户取消');

九仞补充:

const controller = new AbortController();
const signal = controller.signal;

fetch(url, { signal }).then(response => {
  // Handle the response
}).catch(error => {
  if (error.name === 'AbortError') {
    console.log('Request was cancelled');
  } else {
    console.log('Request failed:', error);
  }
});

// To abort the request, call the following:
controller.abort();

js 给的 api 让我们可以随时中断一个 fetch 请求,那么,如果我想造轮子实现这个功能该怎么做呢?

Promise

首先能想到的是用一个 Promise,来包装 fetch 返回的 promise,再使用包装的 Promise.reject 方法来实现中断请求

不过函数返回时我使用了 Promise.race 而不直接返回 abortPromise,原因是因为 fetch 可能返回异常,直接返回包装的 promise 则可能产生无法捕获的异常

以下是示例代码

const fetchAbort = (url: string) => {
  let res, abort;
  const abortPromise = new Promise<Response>((resolve, reject) => {
    res = resolve;
    abort = reject.bind(this, `Fetch "${url}" has been aborted`);
  });
  return {
    response: Promise.race([fetch(url).then(ret => res(ret)), abortPromise]),
    abort
  };
};
const { response, abort } = fetchAbort("./serverConfig.json");
abort();
// abort后,response的promise链将catch到fetch abort消息
// 而不会返回fetch返回的消息
response
  .then(ret => ret.text())
  .then(txt => console.log(txt))
  .catch(err => {
    console.log(err);
  });

输出:

Fetch "./serverConfig.json" has been aborted

代码缺陷也显而易见,这段代码虽然能拦截 fetch 的返回,但是 fetch 占用的网络资源并不会被释放。

也就是说,如果 api 请求还在 pending 状态,控制台 network 列表仍然能看到 fetch 还在请求状态,占用着 io 资源。

所以,如果想要 abort 的同时,释放 fetch 占用的资源,单靠 Promise 是不够的。

XMLHttpRequest.abort()

可以使用 XML 代替 fetch,反正造轮子就是为了绕开 fetch,封装就完了

const fetchAbort = (url: string) => {
  let res, abort, xhr;
  const xhrPromise = new Promise((resolve, reject) => {
    xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (this.status == 200) {
          return resolve(this.response);
        }
        return reject({
          xhr: this,
          msg: "Error",
          status: this.status,
          statusText: this.statusText
        });
      }
    };
    xhr.open("Get", url);
    xhr.send();
  });
  const abortPromise = new Promise((resolve, reject) => {
    res = resolve;
    abort = () => {
      xhr.abort();
      return reject(`Fetch "${url}" has been aborted`);
    };
  });
  return {
    response: Promise.race([xhrPromise.then(ret => res(ret)), abortPromise]),
    abort
  };
};
const { response, abort } = fetchAbort("./serverConfig.json");
abort();
response
  .then(ret => console.log(ret))
  .catch(err => {
    console.log(err);
  });

输出:

Fetch "./serverConfig.json" has been aborted

和 fetch 的原生 abort 代码对比,可以看到请求大小为0B,说明请求虽然发出去了,但是浏览器直接断开了连接,并没有选择接收。于是实现了一个简单的 fetchAbort

不过封装程度还不够,剩下的轮子就不造了,了解原理才是本次造轮子的目的。

加入我们

欢迎加入鱼皮的编程导航知识星球,鱼皮会 1 对 1 回答您的问题、直播带你做出项目、为你定制学习计划和求职指导,还能获取海量编程学习资源,和上万名学编程的同学共享知识、交流进步。

💎 加入星球后,您可以:

1)添加鱼皮本人微信,向他 1 对 1 提问,帮您解决问题、告别迷茫!点击了解详情

2)获取海量编程知识和资源,包括:3000+ 鱼皮的编程答疑和求职指导、原创编程学习路线、几十万字的编程学习知识库、几十 T 编程学习资源、500+ 精华帖等!点击了解详情

3)找鱼皮咨询求职建议和优化简历,次数不限!点击了解详情

4)鱼皮直播从 0 到 1 带大家做出项目,已有 50+ 直播、完结 3 套项目、10+ 项目分享,帮您掌握独立开发项目的能力、丰富简历!点击了解详情

外面一套项目课就上千元了,而星球内所有项目都有指导答疑,轻松解决问题

星球提供的所有服务,都是为了帮您更好地学编程、找到理想的工作。诚挚地欢迎您的加入,这可能是最好的学习机会,也是最值得的一笔投资!

长按扫码领优惠券加入,也可以添加微信 yupi1085 咨询星球(备注“想加星球”):

往期推荐

编程导航,火了!

用口诀轻松记住 HTTP 状态码!

实习面试,遇到了这些问题!

从摆烂到上岸,我抓住了机会!

有了这个项目,我进了大厂!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存