informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Kapan front end perlu mengontrol permintaan bersamaan? Kapan diperlukan beberapa kali untuk meminta data yang diperlukan. Misalnya, jika antarmuka mengembalikan data dalam jumlah besar sekaligus, browser akan terjebak dalam rendering atau bahkan crash. Saat ini, kami dapat mengeluarkan 6 permintaan sekaligus secara batch, untuk menghindari stuck atau crash .
Jadi bagaimana front end mengontrol permintaan bersamaan?
Misalnya ada 20 permintaan, Anda harus mengikuti 3
Setelah kelompok pertama menyelesaikan permintaan, kelompok kedua akan diminta, dan seterusnya.
Ide utamanya adalah menyimpan metode permintaan dan parameter permintaan dalam sebuah array, kemudian meminta 3 sekaligus, dan kemudian meminta 3 berikutnya setelah permintaan selesai. Setelah setiap grup permintaan dikembalikan, hasilnya disimpan, dan setelah semua permintaan dikembalikan, semua hasil dikembalikan.
pControl
: Pengontrol permintaan serentak, melewati jumlah konkurensi maksimum;
add
: Tambahkan permintaan dan parameter;
start
: Mulai permintaan, kembalikan janji, lewati setelah permintaan selesai.then
Dapatkan semua hasil;
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
: Fungsi ini mengembalikan objek yang berisi add
Danstart
Dua metode,add
Digunakan untuk menambahkan tugas dan parameter,start
Digunakan untuk memulai permintaan, ini adalah penutupan.
runAllTasks
: mengembalikan apromise
, lalu masuknew Promise
Dieksekusi secara internal secara rekursifrunTask
, runTask lolosPromise.all
Jalankan permintaan bersamaan diPromise.all().then()
menelepon lagirunTask
, terapkan satu set permintaan untuk dikembalikan, lalu jalankan set permintaan kedua.
Kunci untuk mewujudkan penantian kelompok adalah dengan melakukan
.then
panggilan rekursif.
Berpikir: Bisakah runAllTasks diimplementasikan menggunakan loop?
Ya, perlu digunakan 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
}
Tidak dapat digunakan dalam perulangan for
.then
, jika tidak, loop berikutnya tidak akan menunggu loop sebelumnya.
menggunakan for of
Implementasi berulang:
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
Untuk struktur loop imperatif, jika Anda ingin mencapai efek menunggu dalam loop, Anda harus menggunakanasync
pembungkus fungsi dalam loopawait
,Sedang dalam perbaikan.then
。
forEach
、 map
、 filter
Struktur loop fungsional seperti ini tidak mendukung efek menunggu, karena struktur loop fungsional ini sinkron dan tidak mendukung menunggu.
async
Dan循环
+await
Dikombinasikan untuk mencapai efek menunggu antar loop.
promise.then
Dan递归
Dikombinasikan untuk mencapai efek menunggu antar loop.
pControl
Tetapkan nilai default yang sesuai, setel ke6
, karena nama domain yang sama, permintaan bersamaan browser adalah 6.Kedua peningkatan ini sederhana. Mari kita lihat penggunaannya terlebih dahulu:
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)
})
Apa fungsi panggilan balik awal?
Akan lebih mudah bagi pengguna untuk mendapatkan hasil permintaan bersamaan saat ini dan menghitung kemajuan penyelesaian.
p-control
rilis paket npmdapat diakses npm i p-control
Unduh dan gunakan.
.then
Dikombinasikan dengan rekursi untuk mencapai waktu tunggu di antara tugas-tugas asinkron;for
、while
Tunggu loop danasync
+ await
Digunakan dalam kombinasi untuk mencapai waktu tunggu antara tugas-tugas asinkron;Promise.all
Terapkan beberapa tugas asinkron untuk dijalankan secara bersamaan.