异步等待async/await实现并发请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style></style>
</head>
<body>
<script>
var urls = [
'https://www.kkkk1000.com/images/getImgData/懂法守法.jpg', // 错误地址
'https://www.kkkk1000.com/images/getImgData/ggDF第三方.jpg', // 错误地址
'https://www.kkkk1000.com/images/getImgData/很关键.jpg', // 错误地址
'https://www.kkkk1000.com/images/getImgData/二交换机.jpg', // 错误地址
'https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg',
'https://www.kkkk1000.com/images/getImgData/gray.gif',
'https://www.kkkk1000.com/images/getImgData/Particle.gif',
'https://www.kkkk1000.com/images/getImgData/arithmetic.png',
'https://www.kkkk1000.com/images/getImgData/arithmetic2.gif',
'https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg',
'https://www.kkkk1000.com/images/getImgData/arithmetic.gif',
'https://www.kkkk1000.com/images/wxQrCode2.png',
]
// 扩大待下载图片的数据量
for (i = 0; i < 7; i++) {
urls.push(...urls)
}
// 纯函数---请求下载图片,返回promise对象,成功时resolve,失败时reject
function loadImg(url) {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => {
resolve()
}
img.onerror = reject
img.src = url
})
}
// 同步下载图片
async function syncLoadImg(urls) {
let starTime = new Date()
for (let crtUrl of urls) {
try {
await loadImg(crtUrl)
console.log('本图片链接可下')
} catch (e) {
console.log('突突突突突突,图片不可下啊啊啊')
}
}
let endTime = new Date()
console.log('time', starTime, endTime)
}
// syncLoadImg(urls)
/**
* 并发下载图片,但并发数为limit,
* 任何时候一张图片下载完成或下载失败时,立马发起一张图片下载请求,让并发数控制在limit个
* @param {Array}--url--所有待下载图片集合
* @param {Function}--handler--载图片函数
* @param {Number}--limit--下载的并发数量
*/
async function limitLoadImg(urls, handler, limit) {
let starTime = new Date()
let sequence = [...urls]
// 并发请求队列
let taskQuene = sequence.splice(0, limit).map(async (item, index) => {
// 成功或失败时返回当前项在队列中的索引
try {
await handler(item)
return index
} catch (e) {
return index
}
})
for (const crtUrl of sequence) {
// 获取最快改变状态项的索引
let pIdx = await Promise.race(taskQuene)
console.log('并发任务队列中改变项索引:', pIdx)
// 将任务队列中状态改变项替换成新的下载请求
taskQuene[pIdx] = new Promise(async (resolve, reject) => {
// 成功或失败时返回当前项在队列中的索引
try {
await handler(crtUrl)
resolve(pIdx)
} catch (e) {
resolve(pIdx)
}
})
}
let endTime = new Date()
console.log(starTime, endTime)
}
// limitLoadImg(urls, loadImg, 6)
</script>
</body>
</html>
版权声明:本文为weixin_43752765原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。