学习分享,共勉
题外话,毕竟我工作多年,深知技术改革和创新的方向,Flutter作为跨平台开发技术、Flutter以其美观、快速、高效、开放等优势迅速俘获人心
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
解答提问
如果请求是指网络模型中的一次请求传输,那理所当然是不可能暂停的。
来看看提问者的使用场景 —— JS 发起的请求
,那么可以认为问题当中的请求,应该是指在 JS 运行时中发起的 XMLHttpRequest
或者是 fetch
请求,而请求既然已经发起,那问的自然就是 响应是否能够被暂停 。
我们都知道像大文件分片上传、以及分片下载之类的功能本质上是将分片顺序定好之后按顺序请求,然后就可以通过中断顺序并记录中断点来实现暂停重传的机制,而单个请求并不具备这样的环境。
用 JS 实现 ”假暂停” 机制
虽然不能真正意义上实现暂停请求,但是我们其实可以模拟一个 假暂停 的功能,在前端的业务场景上,数据不是收到就可以直接打在客户脸上的(什么光速打击),前端开发者需要对这些数据进行处理之后渲染在界面上,如果我们能在请求发起之前增加一个控制器,在请求回来时,如果控制器为暂停状态则不处理数据,等待控制器恢复后再进行处理,是不是也能到达到目的?让我们试着实现一下。
假如我们使用 fetch
来请求。我们可以设计一个控制器 Promise
和请求放在一起用 Promise.all
包裹,当 fetch
完成时判断这个控制器的暂停状态,如果没有被暂停,则控制器也直接 resolve,同时整个 Promise.all
也 resolve 抛出。
function _request () {
return new Promise<number>((res) => setTimeout(() => {
res(123)
}, 3000))
}
// 原本想使用 class extends Promise 来实现
// 结果一直出现这个问题 https://github.com/nodejs/node/issues/13678
function createPauseControllerPromise () {
const result = {
isPause: false,
resolveWhenResume: false,
resolve (value?: any) {},
pause () {
this.isPause = true
},
resume () {
if (!this.isPause) return
this.isPause = false
if (this.resolveWhenResume) {
this.resolve()
}
},
promise: Promise.resolve()
}
const promise = new Promise<void>((res) => {
result.resolve = res
})
result.promise = promise
return result
}
function requestWithPauseControl <T extends () => Promise<any>>(request: T) {
const controller = createPauseControllerPromise()
const controlRequest = request().then((data) => {
if (!controller.isPause) controller.resolve()
return data
}).finally(() => {
controller.resolveWhenResume = true
})
const result = Promise.all([controlRequest, controller.promise]).then(data => {
controller.resolve()
return data[0]
});
(result as any).pause = controller.pause.bind(controller);
(result as any).resume = controller.resume.bind(controller);
return result as ReturnType<T> & { pause: () => void, resume: () => void }
}
用法
我们可以通过调用 requestWithPauseControl(_request)
来替代调用 _request
使用,通过返回的 pause
和 resume
方法控制暂停和继续。
const result = requestWithPauseControl(_request).then((data) => {
console.log(data)
})
if (Math.random() > 0.5) { result.pause() }
setTimeout(() => {
result.resume()
}, 4000)
最后
web浏览器中的javascript
- 客户端javascript
- 在html里嵌入javascript
- javascript程序的执行
- 兼容性和互用性
- 可访问性
- 安全性
- 客户端框架
- 开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
window对象
-
计时器
-
浏览器定位和导航
-
浏览历史
-
浏览器和屏幕信息
-
对话框
-
错误处理
-
作为window对象属性的文档元素
浏览器和屏幕信息
-
对话框
-
错误处理
-
作为window对象属性的文档元素