实现点击按钮调用两个api返回图片并交叉显式在页面上

475 阅读2分钟

题目:点击页面按钮,调用两个API: api-a, api-b, 每个api返回10张图片,在页面上交叉显示20张图片: api1_img1, api2_img1, api1_img2, api2_img2, ... 思路:首先需要创建一个axios的实例,再通过axios去向接口发起请求,发起两个请求通过Promise.all来异步实现,将获取到的数据交叉放在一个数组里面,创建文档碎片,遍历数组将图片交叉渲染到页面。

@TOC


一、创建axios实例

代码如下:

	//设置请求头
	const headers = {
		'Content-Type': 'application/json;charset=UTF-8'
		}
	//创建axios实例
	const Axios = axios.create({
			timeout: 30000,//超时时间
			headers
		})

二、用get方法发起请求

代码如下:

function fetchImg (url) {
	return Axios.get(url)
}

二、通过Promise.all发起异步请求

Promise.all([fetchImg("api-a"), fetchImg("api-b")])
.then(res=>{})
.catch(error=>{})

.then是成功时的回调。.catch是捕获异常。

三、设置交叉合并数组的函数

// 交叉合并两个数组成一个数组,arr1和arr2分别为从api-a和api-b获取到的图片数组
		function concatArray (arr1, arr2) {
			if (!arr1.length && !arr2.length) return []
			const arr = []
			let p1 = 0, p2 = 0, count = 1
			while (p1 < arr1.length || p2 < arr2.length) {
				// count是奇数时
				if (count % 2 != 0 && p1 < arr1.length) {
					arr.push(arr1[p1])
					p1++
					count++
					continue
				}
				// count是偶数时
				if (count % 2 == 0 && p2 < arr2.length) {
					arr.push(arr2[p2])
					p2++
					count++
				}
			}
			return arr
		}

四、在load函数内实现api调用并且获取交叉数组

function load () {
			Promise.all([fetchImg("api-a"), fetchImg("api-b")])
			.then(res => {
				if (res) {
					const url1 = res[0], url2 = res[1]
					const urls = concatArray(url1, url2)
				}
			})
			.catch(err => console.log(err))
		}

五、接下来在load函数内创建文档碎片并渲染图片

function load () {
			Promise.all([fetchImg("api-a"), fetchImg("api-b")])
			.then(res => {
				if (res) {
					const url1 = res[0], url2 = res[1]
					const urls = concatArray(url1, url2)
					let oFragmeng = document.createDocumentFragment()
					urls.forEach(url => {
						let img = document.createElement('img');
						img.src = url
						oFragmeng.appendChild(img);
					})
					document.body.appendChild(oFragmeng)
				}
			})
			.catch(err => console.log(err))
		}

六、完整代码如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Static Template</title>
  </head>
  <body>
		<button type="button" onclick="load()">获取图片</button>
  </body>
	<script src="https://unpkg.com/axios@0.27.0/dist/axios.min.js"></script>
	<script type="text/javascript">
		const headers = {
			// 表示后面的文档属于什么MIME类型
			// application/json : JSON数据格式
			// charset=”utf-8”是告知浏览器此页面属于什么字符编码格式
			// unicode:万国码
			// **utf-8:**unicode的升级版。
			'Content-Type': 'application/json;charset=UTF-8'
		}
		const Axios = axios.create({
			timeout: 30000,
			headers
		})
		function load () {
			Promise.all([fetchImg("api-a"), fetchImg("api-b")])
			.then(res => {
				if (res) {
					const url1 = res[0], url2 = res[1]
					const urls = concatArray(url1, url2)
					let oFragmeng = document.createDocumentFragment()
					urls.forEach(url => {
						let img = document.createElement('img');
						img.src = url
						oFragmeng.appendChild(img);
					})
					document.body.appendChild(oFragmeng)
				}
			})
			.catch(err => console.log(err))
		}
		function fetchImg (url) {
			return Axios.get(url)
		}
		// 交叉合并两个数组成一个数组
		function concatArray (arr1, arr2) {
			if (!arr1.length && !arr2.length) return []
			const arr = []
			let p1 = 0, p2 = 0, count = 1
			while (p1 < arr1.length || p2 < arr2.length) {
				// count是奇数时
				if (count % 2 != 0 && p1 < arr1.length) {
					arr.push(arr1[p1])
					p1++
					count++
					continue
				}
				// count是偶数时
				if (count % 2 == 0 && p2 < arr2.length) {
					arr.push(arr2[p2])
					p2++
					count++
				}
			}
			return arr
		}
	</script>
</html>

七、文档碎片

createDocumentFragment()方法,是用来创建一个虚拟的节点对象,或者说,是用来创建文档碎片节点。它可以包含各种类型的节点,在创建之初是空的。 DocumentFragment节点不属于文档树,当请求把一个DocumentFragment节点插入文档树时,插入的不是DocumentFragment自身,而是它的所有子孙节点,即插入的是括号里的节点。也可以将DocumentFragment理解为一个占位符,暂时存放那些一次插入文档的节点。因此,当需要添加多个dom元素时,只需要将这些元素添加到DocumentFragment中,再统一将DocumentFragment添加到页面,会减少页面渲染dom的次数,效率会明显提升,这就是此处使用文档碎片的原因。