setTimeout和XMLHttpRequest

94 阅读3分钟

使用 setTimeout 的一些注意事项

1. 如果当前任务执行时间过久,会影响定时器任务的执行

function bar() {
	console.log('bar')
}
function foo() {
	setTimeout(bar, 0)
  //for循环执行时间长 影响bar的执行
	for (let i = 0; i < 5000; i++) {
		let i = 5 + 8 + 8 + 8
		console.log(i)
	}
}
foo()

2. 如果 setTimeout 存在嵌套调用,那么系统会设置最短时间间隔为 4 毫秒

在 Chrome 中,定时器被嵌套调用 5 次以上,系统会判断该函数方法被阻塞了,如果定时器的调用时间间隔小于 4 毫秒,那么浏览器会将每次调用的时间间隔设置为 4 毫秒

function cb() { setTimeout(cb, 0); }
setTimeout(cb, 0);

3. 未激活的页面,setTimeout 执行最小间隔是 1000 毫秒

4. 延时执行时间有最大值

function showName() {
	console.log('极客时间')
}
var timerID = setTimeout(showName, 2147483648) //会被立刻调用执行

运行后可以看到,这段代码是立即被执行的。但如果将延时值修改为小于 2147483647 毫秒的某个值,那么执行时就没有问题了。

5、使用 setTimeout 设置的回调函数中的 this 不符合直觉

var name = 1
var MyObj = {
	name: 2,
	showName: function () {
		console.log(this.name)
	},
}
//MyObj.showName作为参数传入setTimeout,this指向window,严格模式是undefined
setTimeout(MyObj.showName, 1000)

解决方案1

//箭头函数
setTimeout(() => {
	MyObj.showName()
}, 1000)
//或者function函数
setTimeout(function () {
	MyObj.showName()
}, 1000)

解决方案2

setTimeout(MyObj.showName.bind(MyObj), 1000)

requestAnimationFrame 提供一个原生的API去执行动画的效果,它会在一帧(一般是16ms)间隔内根据选择浏览器情况去执行相关动作。 setTimeout是在特定的时间间隔去执行任务,不到时间间隔不会去执行,这样浏览器就没有办法去自动优化。

XMLHttpRequest是怎么实现的

image.png

XMLHttpRequest 的用法

function GetWebData(URL) {
	/**
	 * 1:新建XMLHttpRequest请求对象
	 */
	let xhr = new XMLHttpRequest()
	/**
	 * 2:注册相关事件回调处理函数
	 */
	xhr.onreadystatechange = function () {
		switch (xhr.readyState) {
			case 0: //请求未初始化
				console.log('请求未初始化')
				break
			case 1: //OPENED
				console.log('OPENED')
				break
			case 2: //HEADERS_RECEIVED
				console.log('HEADERS_RECEIVED')
				break
			case 3: //LOADING
				console.log('LOADING')
				break
			case 4: //DONE
				if (this.status == 200 || this.status == 304) {
					console.log(this.responseText)
				}
				console.log('DONE')
				break
		}
	}
	xhr.ontimeout = function (e) {
		console.log('ontimeout')
	}
	xhr.onerror = function (e) {
		console.log('onerror')
	}
	/**
	 * 3:打开请求
	 */
	xhr.open('Get', URL, true) //创建一个Get请求,采用异步
	/**
	 * 4:配置参数
	 */
	xhr.timeout = 3000 //设置xhr请求的超时时间
	xhr.responseType = 'text' //设置响应返回的数据格式
	xhr.setRequestHeader('X_TEST', 'time.geekbang')
	/**
	 * 5:发送请求
	 */
	xhr.send()
}

XMLHttpRequest 使用过程中的“坑”

1. 跨域问题

2. HTTPS 混合内容的问题

HTTPS 混合内容是 HTTPS 页面中包含了不符合 HTTPS 安全要求的内容,比如包含了 HTTP 资源,通过 HTTP 加载的图像、视频、样式表、脚本等,都属于混合内容。

通过 HTML 文件加载的混合资源,虽然给出警告,但大部分类型还是能加载的。而使用 XMLHttpRequest 请求时,浏览器认为这种请求可能是攻击者发起的,会阻止此类危险的请求

参考文档:浏览器工作原理与实践