minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Quando o front-end precisa controlar solicitações simultâneas? Quando são necessárias várias vezes para solicitar os dados necessários? Por exemplo, se a interface retornar uma grande quantidade de dados de uma vez, o navegador ficará travado na renderização ou até mesmo travará. Nesse momento, podemos emitir 6 solicitações ao mesmo tempo em lotes, para evitar travamentos ou travamentos. .
Então, como o front-end controla as solicitações simultâneas?
Por exemplo, se houver 20 solicitações, você precisará seguir 3
Após o primeiro grupo concluir a solicitação, o segundo grupo será solicitado e assim sucessivamente.
A ideia principal é armazenar o método de solicitação e os parâmetros de solicitação em uma matriz, solicitar 3 de cada vez e solicitar os próximos 3 após a conclusão da solicitação. Após o retorno de cada grupo de solicitações, os resultados são salvos e, após o retorno de todas as solicitações, todos os resultados são retornados.
pControl
: Controlador de solicitações simultâneas, passando o número máximo de simultaneidades;
add
: Adicionar solicitação e parâmetros;
start
: Iniciar solicitação, retornar promessa, passar após a conclusão da solicitação.then
Obtenha todos os resultados;
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
: Esta função retorna um objeto contendo add
estart
Dois métodos,add
Usado para adicionar tarefas e parâmetros,start
Usado para iniciar a solicitação, é um encerramento.
runAllTasks
: retorna umpromise
, e depois emnew Promise
Executado internamente recursivamenterunTask
, runTask passaPromise.all
Executar solicitações simultâneas emPromise.all().then()
ligue novamenterunTask
, implemente um conjunto de solicitações para retornar e, em seguida, execute o segundo conjunto de solicitações.
A chave para concretizar a espera em grupo é
.then
chamada recursiva.
Pensando: runAllTasks pode ser implementado usando um loop?
Sim, preciso usar 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
}
Não pode ser usado em loop for
.then
, caso contrário, o próximo loop não aguardará o loop anterior.
usar for of
Implementação iterativa:
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
Para estruturas de loop imperativas, se você deseja obter o efeito de espera no loop, você deve usarasync
wrapper de função em loopawait
,Fora de serviço.then
。
forEach
、 map
、 filter
Estruturas de loop funcional como essas não suportam efeitos de espera, porque essas estruturas de loop funcional são síncronas e não suportam espera.
async
e循环
+await
Combinado para obter o efeito de espera entre loops.
promise.then
e递归
Combinado para obter o efeito de espera entre loops.
pControl
Defina um valor padrão adequado, definido como6
, como o mesmo nome de domínio está inserido, as solicitações simultâneas do navegador são 6.Essas duas melhorias são simples. Vejamos primeiro o uso:
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)
})
O que o retorno de chamada inicial faz?
É conveniente para os usuários obterem os resultados das solicitações simultâneas atuais e calcularem o progresso da conclusão.
p-control
lançamento do pacote npmacessível npm i p-control
Baixe e use.
.then
Combinado com recursão para conseguir espera entre tarefas assíncronas;for
、while
Aguarde o loop easync
+ await
Usado em combinação para obter espera entre tarefas assíncronas;Promise.all
Implemente várias tarefas assíncronas para serem executadas simultaneamente.