JavaScript 在循环中调用异步
1.技术栈
Promise
async await
2.实现代码
直接复制代码就可运行。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
</style>
</head>
<body>
<script>
/**
* 模拟发送请求
* @param url
* @returns {Promise<unknown>}
*/
function request(url, otherData, dynamicsParams) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('请求结束:请求URL为' + url, '请求入参为:' + otherData, '动态入参:' + dynamicsParams)
if (Math.random() > 0.3) {
resolve('请求成功:返回数据为随机数:' + Math.random())
} else {
reject('请求错误:返回错误信息:xxx')
}
}, 1 * 2e3)
})
}
/**
* 按顺序执行,前一个执行完成再执行下一个。
* @param requestList
* @param callback
*/
function sendRequest(requestList, callback) {
console.log('按顺序执行接口。。。')
// 取得请求list(浅拷贝一份)
const promises = requestList.slice()
// 第一次先跑起可以并发的任务
const runTaskNeeded = async () => {
// 上一次执行的成功的结果
const allResponseResult = []
// 启动当前能执行的任务
while (promises.length > 0) {
const task = promises.shift() // 从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
console.log('--------------------------------------------------------分割线---------------------------------------------------------')
console.log('正在执行==>', task)
// 执行任务,同时把上次的执行结果作为下一次执行的参数
const result = await task('这是动态参数哈').catch(err => {
console.log('发生了错误的结果:' + err)
allResponseResult.push(err)
})
allResponseResult.push(result)
console.log('执行成功的结果:' + allResponseResult)
}
if (promises.length == 0) {
callback && callback(allResponseResult)
}
}
// 入口执行
runTaskNeeded()
}
// 模拟4个请求
const requestList = [
(dynamicsParams) => request('http://localhost/1', 'otherData1', dynamicsParams),
() => request('http://localhost/2', 'otherData2', null),
() => request('http://localhost/3', 'otherData3', null)
]
// 调用
sendRequest(requestList, (result) => {
console.log('全部执行完毕', result)
})
</script>
</body>
</html>