2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Wann muss das Frontend gleichzeitige Anforderungen steuern? Wenn die Anforderung der erforderlichen Daten mehrmals erforderlich ist. Wenn die Schnittstelle beispielsweise eine große Datenmenge auf einmal zurückgibt, bleibt der Browser beim Rendern hängen oder stürzt sogar ab. Zu diesem Zeitpunkt können wir 6 Anfragen gleichzeitig in Stapeln ausgeben, um ein Hängenbleiben oder einen Absturz zu vermeiden .
Wie steuert das Frontend gleichzeitige Anfragen?
Wenn es beispielsweise 20 Anfragen gibt, müssen Sie diesen folgen 3
Nachdem die erste Gruppe die Anfrage abgeschlossen hat, wird die zweite Gruppe angefordert und so weiter.
Die Schlüsselidee besteht darin, die Anforderungsmethode und die Anforderungsparameter in einem Array zu speichern, dann jeweils drei anzufordern und nach Abschluss der Anforderung die nächsten drei anzufordern. Nachdem jede Gruppe von Anforderungen zurückgegeben wurde, werden die Ergebnisse gespeichert, und nachdem alle Anforderungen zurückgegeben wurden, werden alle Ergebnisse zurückgegeben.
pControl
: Concurrent-Request-Controller, der die maximale Anzahl von Parallelitäten weitergibt;
add
: Anfrage und Parameter hinzufügen;
start
: Anfrage starten, Versprechen zurückgeben, bestehen, nachdem die Anfrage abgeschlossen ist.then
Erhalten Sie alle Ergebnisse;
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
: Diese Funktion gibt ein Objekt zurück, das enthält add
Undstart
Zwei Methoden,add
Wird zum Hinzufügen von Aufgaben und Parametern verwendet.start
Wird zum Starten der Anfrage verwendet und ist ein Abschluss.
runAllTasks
: gibt a zurückpromise
, und dann reinnew Promise
Intern rekursiv ausgeführtrunTask
, runTask ist erfolgreichPromise.all
Gleichzeitige Anforderungen ausführen inPromise.all().then()
erneut aufrufenrunTask
, implementieren Sie einen Satz von Rückgabeanforderungen und führen Sie dann den zweiten Satz von Anforderungen aus.
Der Schlüssel zur Verwirklichung des Gruppenwartens liegt darin
.then
rekursiver Aufruf.
Überlegung: Kann runAllTasks mithilfe einer Schleife implementiert werden?
Ja, muss verwendet werden 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
}
Kann nicht in einer for-Schleife verwendet werden
.then
, andernfalls wartet die nächste Schleife nicht auf die vorherige Schleife.
verwenden for of
Iterative Implementierung:
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
Wenn Sie bei zwingenden Schleifenstrukturen den Warteeffekt in der Schleife erzielen möchten, müssen Sie verwendenasync
Funktions-Wrapper in Schleifeawait
,Außer Betrieb.then
。
forEach
、 map
、 filter
Funktionsschleifenstrukturen wie diese unterstützen keine Warteeffekte, da diese Funktionsschleifenstrukturen synchron sind und kein Warten unterstützen.
async
Und循环
+await
Kombiniert, um den Warteeffekt zwischen Schleifen zu erzielen.
promise.then
Und递归
Kombiniert, um den Warteeffekt zwischen Schleifen zu erzielen.
pControl
Legen Sie einen geeigneten Standardwert fest und setzen Sie ihn auf6
Da derselbe Domänenname vorhanden ist, beträgt die Anzahl der gleichzeitigen Anforderungen des Browsers 6.Diese beiden Verbesserungen sind einfach. Schauen wir uns zunächst die Verwendung an:
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)
})
Was bewirkt der Start-Callback?
Für Benutzer ist es praktisch, die Ergebnisse aktueller gleichzeitiger Anforderungen abzurufen und den Abschlussfortschritt zu berechnen.
p-control
Veröffentlichung des NPM-Paketszugänglich npm i p-control
Herunterladen und verwenden.
.then
Kombiniert mit Rekursion, um das Warten zwischen asynchronen Aufgaben zu erreichen;for
、while
Warten Sie auf die Schleife undasync
+ await
Wird in Kombination verwendet, um das Warten zwischen asynchronen Aufgaben zu erreichen.Promise.all
Implementieren Sie mehrere asynchrone Aufgaben zur gleichzeitigen Ausführung.