le mie informazioni di contatto
Posta[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Quando è necessario che il front-end controlli le richieste simultanee Quando sono necessarie più volte per richiedere i dati richiesti? Ad esempio, se l'interfaccia restituisce molti dati contemporaneamente, il browser si bloccherà nel rendering o addirittura si bloccherà. In questo momento, possiamo inviare 6 richieste contemporaneamente in batch, in modo da evitare blocchi o arresti anomali.
Quindi, come fa il front-end a controllare le richieste simultanee?
Ad esempio, se ci sono 20 richieste, devi seguire 3
Dopo che il primo gruppo avrà completato la richiesta, verrà richiesta la richiesta al secondo gruppo e così via.
L'idea chiave è memorizzare il metodo di richiesta e i parametri di richiesta in un array, quindi richiederne 3 alla volta e quindi richiedere i 3 successivi una volta completata la richiesta. Dopo la restituzione di ciascun gruppo di richieste, i risultati vengono salvati e, dopo la restituzione di tutte le richieste, vengono restituiti tutti i risultati.
pControl
: controller delle richieste simultanee, che supera il numero massimo di simultanee;
add
: Aggiungi richiesta e parametri;
start
: Avvia richiesta, promessa di restituzione, passaggio dopo il completamento della richiesta.then
Ottieni tutti i risultati;
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
: Questa funzione restituisce un oggetto contenente add
Estart
Due metodi,add
Utilizzato per aggiungere attività e parametri,start
Utilizzato per avviare la richiesta, è una chiusura.
runAllTasks
: restituisce apromise
, e poi dentronew Promise
Eseguito internamente in modo ricorsivorunTask
, runTask passaPromise.all
Esegui richieste simultanee inPromise.all().then()
chiamare di nuovorunTask
, implementare un set di richieste da restituire e quindi eseguire il secondo set di richieste.
La chiave per realizzare l’attesa di gruppo è
.then
chiamata ricorsiva.
Pensiero: è possibile implementare runAllTasks utilizzando un loop?
Sì, è necessario utilizzarlo 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
}
Non può essere utilizzato nel ciclo for
.then
, altrimenti il ciclo successivo non attenderà il ciclo precedente.
utilizzo for of
Implementazione 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
Per le strutture di loop imperative, se si desidera ottenere l'effetto di attesa nel loop, è necessario utilizzareasync
wrapper di funzioni nel cicloawait
,Fuori servizio.then
。
forEach
、 map
、 filter
Strutture di loop funzionali come queste non supportano gli effetti di attesa, poiché queste strutture di loop funzionali sono sincrone e non supportano l'attesa.
async
E循环
+await
Combinato per ottenere l'effetto di attesa tra i cicli.
promise.then
E递归
Combinato per ottenere l'effetto di attesa tra i cicli.
pControl
Impostare un valore predefinito adatto, impostare su6
, poiché si trova lo stesso nome di dominio, le richieste simultanee del browser sono 6.Questi due miglioramenti sono semplici. Diamo prima un'occhiata all'utilizzo:
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)
})
Cosa fa la richiamata iniziale?
È conveniente per gli utenti ottenere i risultati delle richieste simultanee correnti e calcolare l'avanzamento del completamento.
p-control
rilascio del pacchetto npmaccessibile npm i p-control
Scarica e utilizza.
.then
Combinato con la ricorsione per ottenere l'attesa tra attività asincrone;for
、while
Aspetta il ciclo easync
+ await
Utilizzato in combinazione per ottenere l'attesa tra attività asincrone;Promise.all
Implementa più attività asincrone da eseguire contemporaneamente.