Mi informacion de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
¿Cuándo necesita la interfaz controlar las solicitudes simultáneas? ¿Cuándo se necesitan varias veces para solicitar los datos requeridos? Por ejemplo, si la interfaz devuelve una gran cantidad de datos a la vez, el navegador se bloqueará en el procesamiento o incluso fallará. En este momento, podemos emitir 6 solicitudes al mismo tiempo en lotes para evitar bloqueos o fallas. .
Entonces, ¿cómo controla el front-end las solicitudes concurrentes?
Por ejemplo, si hay 20 solicitudes, debes seguir 3
Una vez que el primer grupo complete la solicitud, se solicitará al segundo grupo, y así sucesivamente.
La idea clave es almacenar el método de solicitud y los parámetros de solicitud en una matriz, luego solicitar 3 a la vez y luego solicitar los 3 siguientes una vez completada la solicitud. Después de que regresa cada grupo de solicitudes, se guardan los resultados y, una vez que se devuelven todas las solicitudes, se devuelven todos los resultados.
pControl
: Controlador de solicitudes concurrentes, que pasa el número máximo de concurrencias;
add
: Agregar solicitud y parámetros;
start
: Iniciar solicitud, devolver promesa, pasar después de completar la solicitud.then
Obtenga todos los 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 función devuelve un objeto que contiene add
ystart
Dos métodos,add
Se utiliza para agregar tareas y parámetros,start
Se utiliza para iniciar la solicitud, es un cierre.
runAllTasks
: devuelve unpromise
, y luego ennew Promise
Ejecutado internamente de forma recursivarunTask
, ejecutarPases de tareaPromise.all
Ejecutar solicitudes simultáneas enPromise.all().then()
llama de nuevorunTask
, implemente un conjunto de solicitudes para devolver y luego ejecute el segundo conjunto de solicitudes.
La clave para lograr la espera grupal es
.then
llamada recursiva.
Pensando: ¿Se puede implementar runAllTasks mediante un bucle?
Sí, necesito 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
}
No se puede utilizar en el bucle for
.then
; de lo contrario, el siguiente bucle no esperará al bucle anterior.
usar for of
Implementación 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 estructuras de bucle imperativo, si desea lograr el efecto de espera en el bucle, debe usarasync
contenedor de funciones en bucleawait
,Fuera de servicio.then
。
forEach
、 map
、 filter
Las estructuras de bucle funcionales como éstas no admiten efectos de espera, porque estas estructuras de bucle funcionales son síncronas y no admiten la espera.
async
y循环
+await
Combinado para lograr el efecto de espera entre bucles.
promise.then
y递归
Combinado para lograr el efecto de espera entre bucles.
pControl
Establezca un valor predeterminado adecuado, establecido en6
Debido a que tiene el mismo nombre de dominio, las solicitudes simultáneas del navegador son 6.Estas dos mejoras son simples. Veamos primero el 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)
})
¿Qué hace la devolución de llamada de inicio?
Es conveniente para los usuarios obtener los resultados de las solicitudes simultáneas actuales y calcular el progreso de finalización.
p-control
lanzamiento del paquete npmaccesible npm i p-control
Descargar y usar.
.then
Combinado con recursividad para lograr la espera entre tareas asincrónicas;for
、while
Espere el bucle yasync
+ await
Se utiliza en combinación para lograr la espera entre tareas asincrónicas;Promise.all
Implemente múltiples tareas asincrónicas para ejecutarlas simultáneamente.