내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
프런트 엔드는 언제 동시 요청을 제어해야 합니까? 필요한 데이터를 요청하는 데 여러 번 걸리는 경우 예를 들어, 인터페이스가 한 번에 많은 데이터를 반환하는 경우 브라우저가 렌더링에 멈추거나 심지어 충돌할 수도 있습니다. 이때 우리는 멈추거나 충돌하는 것을 방지하기 위해 동시에 6개의 요청을 일괄 전송할 수 있습니다.
그렇다면 프런트 엔드는 동시 요청을 어떻게 제어합니까?
예를 들어 요청이 20개라면 다음을 따라야 합니다. 3
첫 번째 그룹이 요청을 완료한 후 두 번째 그룹이 요청되는 방식으로 진행됩니다.
핵심 아이디어는 요청 메소드와 요청 매개변수를 배열에 저장한 후 한 번에 3개를 요청하고 요청이 완료된 후 다음 3개를 요청하는 것입니다. 각 요청 그룹이 반환된 후 결과가 저장되고, 모든 요청이 반환된 후 모든 결과가 반환됩니다.
pControl
: 동시 요청 컨트롤러, 최대 동시성 수를 전달합니다.
add
: 요청 및 매개변수를 추가합니다.
start
: 요청 시작, 약속 반환, 요청 완료 후 통과.then
모든 결과를 얻으십시오.
function pControl(limit) {
const taskQueue = [] // {task: Function, params: any[]}[]
return {
add,
start
}
function add(task, params) {
taskQueue.push({
task,
params
})
}
function start() {
return runAllTasks()
}
function runAllTasks() {
const allResults = []
return new Promise((resolve) => {
runTask()
function runTask() {
if (taskQueue.length === 0) {
// 递归结束
return resolve(allResults)
}
const needRunSize = Math.min(taskQueue.length, limit)
const tasks = taskQueue.splice(0, needRunSize)
const promises = tasks.map(({
task,
params
}) => task(params))
Promise.all(promises).then((resList) => {
allResults.push(...resList)
// NOTE 递归调用的位置很关键
runTask()
})
}
})
}
}
pControl
: 이 함수는 다음을 포함하는 객체를 반환합니다. add
그리고start
두 가지 방법,add
작업 및 매개변수를 추가하는 데 사용됩니다.start
요청을 시작하는 데 사용되며 폐쇄입니다.
runAllTasks
:를 반환합니다.promise
, 그런 다음new Promise
내부적으로 재귀적으로 실행됨runTask
, runTask 통과Promise.all
동시 요청 실행Promise.all().then()
다시 전화하세요runTask
, 반환할 요청 세트 하나를 구현한 다음 두 번째 요청 세트를 실행합니다.
그룹 기다림을 실현하는 열쇠는
.then
재귀 호출.
생각: 루프를 사용하여 runAllTasks를 구현할 수 있습니까?
응, 사용해야 해 async 和 for 循环 + await
:
async function runAllTasks2() {
const allResults = []
const groupArr = []
let startIndex = 0
// 划分分组
while (startIndex < taskQueue.length) {
const arr = taskQueue.slice(startIndex, startIndex + limit)
groupArr.push(arr)
startIndex += limit
}
for (let index = 0; index < groupArr.length; index++) {
const pList = groupArr[index].map(({
task,
params
}) => task(params))
const res = await Promise.all(pList)
allResults.push(...res)
}
return allResults
}
for 루프에서는 사용할 수 없습니다
.then
그렇지 않으면 다음 루프는 이전 루프를 기다리지 않습니다.
사용 for of
반복적 구현:
async function runAllTasks2() {
const allResults = []
const groupArr = []
let startIndex = 0
// 划分分组
while (startIndex < taskQueue.length) {
const arr = taskQueue.slice(startIndex, startIndex + limit)
groupArr.push(arr)
startIndex += limit
}
// 迭代分组
const it = groupArr.entries()
for (const [key, value] of it) {
const pList = value.map(({
task,
params
}) => task(params))
const res = await Promise.all(pList)
allResults.push(...res)
}
return allResults
}
for
、 while
、 for...of
명령형 루프 구조의 경우 루프에서 대기 효과를 얻으려면 다음을 사용해야 합니다.async
루프의 함수 래퍼await
,서비스 중단.then
。
forEach
、 map
、 filter
이와 같은 기능 루프 구조는 대기 효과를 지원하지 않습니다. 왜냐하면 이러한 기능 루프 구조는 동기식이고 대기를 지원하지 않기 때문입니다.
async
그리고循环
+await
루프 간 대기 효과를 얻기 위해 결합됩니다.
promise.then
그리고递归
루프 간 대기 효과를 얻기 위해 결합됩니다.
pControl
적절한 기본값을 설정하고 다음으로 설정하십시오.6
, 동일한 도메인 이름이 있으므로 브라우저의 동시 요청은 6입니다.이 두 가지 개선 사항은 간단합니다. 먼저 사용법을 살펴보겠습니다.
const asyncTaskControl = pControl() // 默认 6
asyncTaskControl.add(task, params1)
asyncTaskControl.add(task, params2)
// ...
asyncTaskControl.add(task, params10)
asyncTaskControl.start((res, doneSize) => {
// 获取每组请求的结果 和当前完成了多少请求
console.log(res) // [{index:number,result:data}]
console.log(doneSize)
}).then(allResults => {
// 所有请求结果
console.log(allResults)
})
시작 콜백은 무엇을 합니까?
사용자는 현재 동시 요청의 결과를 가져오고 완료 진행률을 계산하는 것이 편리합니다.
p-control
npm 패키지 출시얻기 쉬운 npm i p-control
다운로드하여 사용하세요.
.then
재귀와 결합하여 비동기 작업 간 대기를 달성합니다.for
、while
루프를 기다리고async
+ await
비동기 작업 간 대기를 달성하기 위해 조합하여 사용됩니다.Promise.all
동시에 실행할 여러 비동기 작업을 구현합니다.