2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Milloin käyttöliittymän on ohjattava samanaikaisia pyyntöjä, kun vaadittujen tietojen pyytäminen kestää useita kertoja? Esimerkiksi jos käyttöliittymä palauttaa suuren määrän dataa kerralla, selain jumissa renderöinnissa tai jopa kaatuu. Tällä hetkellä voimme lähettää 6 pyyntöä samanaikaisesti erissä välttääksemme jumiutumisen tai kaatumisen. .
Joten miten käyttöliittymä hallitsee samanaikaisia pyyntöjä?
Jos pyyntöjä on esimerkiksi 20, sinun on noudatettava sitä 3
Kun ensimmäinen ryhmä on suorittanut pyynnön, toinen ryhmä pyytää ja niin edelleen.
Keskeisenä ideana on tallentaa pyyntömenetelmä ja pyyntöparametrit taulukkoon, sitten pyytää 3 kerrallaan ja sitten pyytää seuraavaa 3 pyynnön valmistuttua. Kun jokainen pyyntöryhmä palaa, tulokset tallennetaan, ja kun kaikki pyynnöt on palautettu, kaikki tulokset palautetaan.
pControl
: Samanaikaisen pyynnön ohjain, joka läpäisee enimmäismäärän samanaikaisuuksia;
add
: Lisää pyyntö ja parametrit;
start
: Aloita pyyntö, palauta lupaus, hyväksy, kun pyyntö on suoritettu.then
Hanki kaikki tulokset;
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
: Tämä funktio palauttaa objektin, joka sisältää add
jastart
Kaksi tapaa,add
Käytetään tehtävien ja parametrien lisäämiseen,start
Käytetään pyynnön aloittamiseen, se on sulkeminen.
runAllTasks
: palauttaa apromise
, ja sitten sisäännew Promise
Sisäisesti suoritettu rekursiivisestirunTask
, RunTask kulkeePromise.all
Suorita samanaikaiset pyynnöt sisäänPromise.all().then()
soita uudelleenrunTask
, toteuttaa yksi palautuspyyntösarja ja suorittaa sitten toinen pyyntösarja.
Avain ryhmän odottamisen toteuttamiseen on
.then
rekursiivinen puhelu.
Ajatteleminen: Voidaanko runAllTasks toteuttaa silmukan avulla?
Kyllä, pitää käyttää 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
}
Ei voida käyttää silmukassa
.then
, muuten seuraava silmukka ei odota edellistä silmukkaa.
käyttää for of
Iteratiivinen toteutus:
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
Pakollisten silmukkarakenteiden kohdalla, jos haluat saavuttaa odottavan vaikutuksen silmukassa, sinun on käytettäväasync
funktion kääre silmukassaawait
,Poissa käytöstä.then
。
forEach
、 map
、 filter
Tällaiset toiminnalliset silmukkarakenteet eivät tue odotusefektejä, koska nämä toiminnalliset silmukkarakenteet ovat synkronisia eivätkä tue odottelua.
async
ja循环
+await
Yhdistetty odotusvaikutuksen saavuttamiseksi silmukoiden välillä.
promise.then
ja递归
Yhdistetty odotusvaikutuksen saavuttamiseksi silmukoiden välillä.
pControl
Aseta sopiva oletusarvo, aseta arvoksi6
, koska sama verkkotunnus on sisällä, selaimen samanaikaiset pyynnöt ovat 6.Nämä kaksi parannusta ovat yksinkertaisia. Katsotaanpa ensin käyttöä:
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)
})
Mitä aloitussoitto tekee?
Käyttäjien on kätevää saada nykyisten samanaikaisten pyyntöjen tulokset ja laskea valmistumisen edistyminen.
p-control
npm paketin julkaisusaatavilla npm i p-control
Lataa ja käytä.
.then
Yhdessä rekursion kanssa odottamisen saavuttamiseksi asynkronisten tehtävien välillä;for
、while
Odota silmukkaa jaasync
+ await
Käytetään yhdessä odottamaan asynkronisten tehtävien välillä;Promise.all
Toteuta useita asynkronisia tehtäviä suoritettavaksi samanaikaisesti.