Heim Web-Frontend js-Tutorial So optimieren Sie die asynchrone js-Funktion

So optimieren Sie die asynchrone js-Funktion

May 30, 2018 am 10:16 AM
async javascript 优化

Dieses Mal zeige ich Ihnen, wie Sie die js-asynchrone Funktion optimieren. Was sind die Vorsichtsmaßnahmen für die Optimierung der js-asynchronen Funktion?

Zunächst müssen Sie Promise verstehen

Promise ist die Grundlage für die Verwendung von async/await, daher müssen Sie zunächst verstehen, was Promise tut

Versprechen ist eine gute Sache, um die Callback-Hölle zu lösen und asynchrone Prozesse klarer zu machen.

Ein einfaches Beispiel für die Konvertierung von Error-first-callback in Promise:

const fs = require('fs')
function readFile (fileName) {
 return new Promise((resolve, reject) => {
  fs.readFile(fileName, (err, data) => {
   if (err) reject(err)
   resolve(data)
  })
 })
}
readFile('test.log').then(data => {
 console.log('get data')
}, err => {
 console.error(err)
})
Nach dem Login kopieren

Wir rufen die Funktion auf, um eine Promise-Instanz zurückzugeben, und lesen die Datei während des Instanziierungsprozesses Der Rückruf wird ausgelöst, um den Promise-Status zu ändern. Wir verwenden dann, um Änderungen im gelösten oder abgelehnten Status zu überwachen. Der erste Rückruf dient der Auflösungsverarbeitung und der zweite Rückruf dient der Ablehnungsverarbeitung.

Die Beziehung zwischen Async und Promise

Die Async-Funktion entspricht einer Kurzfunktion, die eine Promise-Instanz zurückgibt. Der Effekt ist wie folgt :

function getNumber () {
 return new Promise((resolve, reject) => {
  resolve(1)
 })
}
// =>
async function getNumber () {
 return 1
}
Nach dem Login kopieren

Die beiden Methoden sind in der Anwendung genau gleich. Sie können sie dann verwenden, um den Rückgabewert nach dem Aufruf der getNumber-Funktion zu überwachen. Und wie man die Async-Await-Syntax verwendet: Die Ausführung von

getNumber().then(data => {
 // got data
})
// =>
let data = await getNumber()
Nach dem Login kopieren

await erhält das Promise-Ausführungsergebnis hinter dem -Ausdruck , was unserem Aufruf von then entspricht, um das Rückrufergebnis zu erhalten . P.S. Als die Async/Await-Unterstützung nicht sehr hoch war, würde sich jeder dafür entscheiden, Generator/Yield in Kombination mit einigen Co-ähnlichen Bibliotheken zu verwenden, um ähnliche Effekte zu erzielen.

Die Ausführung des Async-Funktionscodes erfolgt synchron und das Ergebnis wird zurückgegeben asynchron

Es ist sehr wichtig, dass die asynchrone Funktion immer eine Promise-Instanz zurückgibt. Wenn Sie also eine asynchrone Funktion aufrufen, können Sie verstehen, dass sich der darin enthaltene Code in einem neuen Promise befindet und daher synchron ausgeführt wird. Die endgültige Rückgabe Die Operation entspricht dem Aufruf von „resolution“ im Versprechen:

async function getNumber () {
 console.log('call getNumber()')
 return 1
}
getNumber().then(_ => console.log('resolved'))
console.log('done')
// 输出顺序:
// call getNumber()
// done
// resolved
Nach dem Login kopieren

Das Versprechen innerhalb des Versprechens wird verdaut

das heißt, wenn wir haben den folgenden Code:

function getNumber () {
 return new Promise(resolve => {
  resolve(Promise.resolve(1))
 })
}
getNumber().then(data => console.log(data)) // 1
Nach dem Login kopieren

Wenn wir dem oben Gesagten folgen, sollten die Daten, die wir dann erhalten, der Wert sein, der an „resolve“ übergeben wird, was eine weitere Promise-Instanz ist.
Tatsächlich erhalten wir jedoch den Rückgabewert direkt: 1. Das heißt, wenn in Promise ein Promise zurückgegeben wird, hilft uns das Programm tatsächlich bei der Ausführung dieses Promises und löst dann einen Rückruf aus, wenn sich der interne Promise-Status ändert .
Eine interessante Sache:

function getNumber () {
 return new Promise(resolve => {
  resolve(Promise.reject(new Error('Test')))
 })
}
getNumber().catch(err => console.error(err)) // Error: Test
Nach dem Login kopieren

Wenn wir in Resolve eine Ablehnung übergeben, können wir sie direkt mit „catch“ extern überwachen.
Diese Methode wird oft verwendet, um Ausnahmen in asynchronen Funktionen auszulösen So lösen Sie Ausnahmen in asynchronen Funktionen aus:

async function getNumber () {
 return Promise.reject(new Error('Test'))
}
try {
 let number = await getNumber()
} catch (e) {
 console.error(e)
}
Nach dem Login kopieren

Achten Sie darauf, die Schlüsselwörter „await“ nicht zu vergessen

Wenn Sie vergessen, das Schlüsselwort „await“ hinzuzufügen, wird auf Codeebene kein Fehler gemeldet, aber der Rückgabewert, den wir erhalten, ist ein Versprechen

let number = getNumber()
console.log(number) // Promise
Nach dem Login kopieren

, also sei so Verwenden Sie es unbedingt. Denken Sie daran, dass das Schlüsselwort „await“

let number = await getNumber()
console.log(number) // 1
Nach dem Login kopieren
Nach dem Login kopieren

nicht überall hinzugefügt werden muss

Während der Ausführung des Codes müssen manchmal nicht alle asynchronen Vorgänge „await“ hinzufügen. Zum Beispiel die folgende Dateioperation:

Wir gehen davon aus, dass alle fs-APIs von uns in Promise-Versionen konvertiert wurden

let number = await getNumber()
console.log(number) // 1
Nach dem Login kopieren
Nach dem Login kopieren

Wir öffnen eine Datei über „await“ und schreiben die Datei dann zweimal.

Beachten Sie jedoch, dass wir das Schlüsselwort „await“ nicht vor den beiden Dateischreibvorgängen hinzugefügt haben.
Da dies überflüssig ist, müssen wir der API nur mitteilen, dass ich eine Textzeile in diese Datei schreiben möchte. Die Reihenfolge wird natürlich von fs gesteuert.
Dann verwenden wir „await“, um die Datei am Ende zu schließen .
Denn wenn wir den obigen Schreibvorgang ausführen, wird der Close-Callback nicht ausgelöst.
Mit anderen Worten: Das Auslösen des Callbacks bedeutet, dass die beiden oben genannten Schreibschritte abgeschlossen sind.

Mehrere unabhängige asynchrone Funktionsaufrufe zusammenführen

Wenn wir jetzt den Avatar und die Benutzerdetails eines Benutzers abrufen möchten (und dies sind zwei Schnittstellen, obwohl sie unter normalen Umständen selten auftreten)

async function getUser () {
 let avatar = await getAvatar()
 let userInfo = await getUserInfo()
 return {
  avatar,
  userInfo
 }
}
Nach dem Login kopieren

这样的代码就造成了一个问题,我们获取用户信息的接口并不依赖于头像接口的返回值。
 但是这样的代码却会在获取到头像以后才会去发送获取用户信息的请求。
 所以我们对这种代码可以这样处理:

async function getUser () {
 let [avatar, userInfo] = await Promise.all([getAvatar(), getUserInfo()])
 return {
  avatar,
  userInfo
 }
}
Nach dem Login kopieren

这样的修改就会让getAvatar与getUserInfo内部的代码同时执行,同时发送两个请求,在外层通过包一层Promise.all来确保两者都返回结果。

让相互没有依赖关系的异步函数同时执行

一些循环中的注意事项

forEach

当我们调用这样的代码时:

async function getUsersInfo () {
 [1, 2, 3].forEach(async uid => {
  console.log(await getUserInfo(uid))
 })
}
function getuserInfo (uid) {
 return new Promise(resolve => {
  setTimeout(_ => resolve(uid), 1000)
 })
}
await getUsersInfo()
Nach dem Login kopieren

这样的执行好像并没有什么问题,我们也会得到1、2、3三条log的输出,但是当我们在await getUsersInfo()下边再添加一条console.log('done')的话,就会发现:

 我们会先得到done,然后才是三条uid的log,也就是说,getUsersInfo返回结果时,其实内部Promise并没有执行完。
 这是因为forEach并不会关心回调函数的返回值是什么,它只是运行回调。

不要在普通的for、while循环中使用await

使用普通的for、while循环会导致程序变为串行:

for (let uid of [1, 2, 3]) {
 let result = await getUserInfo(uid)
}
Nach dem Login kopieren

这样的代码运行,会在拿到uid: 1的数据后才会去请求uid: 2的数据

--------------------------------------------------------------------------------

关于这两种问题的解决方案:

目前最优的就是将其替换为map结合着Promise.all来实现:

await Promise.all([1, 2, 3].map(async uid => await getUserInfo(uid)))
Nach dem Login kopieren
Nach dem Login kopieren

这样的代码实现会同时实例化三个Promise,并请求getUserInfo

P.S. 草案中有一个await*,可以省去Promise.all

await Promise.all([1, 2, 3].map(async uid => await getUserInfo(uid)))
Nach dem Login kopieren
Nach dem Login kopieren

P.S. 为什么在使用Generator+co时没有这个问题

在使用koa1.x的时候,我们直接写yield [].map是不会出现上述所说的串行问题的看过co源码的小伙伴应该都明白,里边有这么两个函数(删除了其余不相关的代码):

function toPromise(obj) {
 if (Array.isArray(obj)) return arrayToPromise.call(this, obj);
 return obj;
}
function arrayToPromise(obj) {
 return Promise.all(obj.map(toPromise, this));
}
Nach dem Login kopieren

co是帮助我们添加了Promise.all的处理的(膜拜TJ大佬)。

总结

总结一下关于async函数编写的几个小提示:

1.使用return Promise.reject()在async函数中抛出异常
2.让相互之间没有依赖关系的异步函数同时执行
3.不要在循环的回调中/for、while循环中使用await,用map来代替它

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样使用垃圾回收器

怎样使用Nodejs内存治理

怎样使用vue的toast弹窗组件

Das obige ist der detaillierte Inhalt vonSo optimieren Sie die asynchrone js-Funktion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Ausführliche Interpretation: Warum ist Laravel so langsam wie eine Schnecke? Ausführliche Interpretation: Warum ist Laravel so langsam wie eine Schnecke? Mar 07, 2024 am 09:54 AM

Laravel ist ein beliebtes PHP-Entwicklungsframework, wird jedoch manchmal dafür kritisiert, dass es so langsam wie eine Schnecke ist. Was genau verursacht die unbefriedigende Geschwindigkeit von Laravel? In diesem Artikel werden die Gründe, warum Laravel in vielerlei Hinsicht so langsam wie eine Schnecke ist, ausführlich erläutert und mit spezifischen Codebeispielen kombiniert, um den Lesern zu einem tieferen Verständnis dieses Problems zu verhelfen. 1. Probleme mit der ORM-Abfrageleistung In Laravel ist ORM (Object Relational Mapping) eine sehr leistungsstarke Funktion, die dies ermöglicht

Diskussion über Golangs GC-Optimierungsstrategie Diskussion über Golangs GC-Optimierungsstrategie Mar 06, 2024 pm 02:39 PM

Die Garbage Collection (GC) von Golang war schon immer ein heißes Thema unter Entwicklern. Als schnelle Programmiersprache kann der integrierte Garbage Collector von Golang den Speicher sehr gut verwalten, mit zunehmender Programmgröße treten jedoch manchmal Leistungsprobleme auf. In diesem Artikel werden die GC-Optimierungsstrategien von Golang untersucht und einige spezifische Codebeispiele bereitgestellt. Die Garbage Collection im Garbage Collector von Golang Golang basiert auf gleichzeitigem Mark-Sweep (concurrentmark-s

C++-Programmoptimierung: Techniken zur Reduzierung der Zeitkomplexität C++-Programmoptimierung: Techniken zur Reduzierung der Zeitkomplexität Jun 01, 2024 am 11:19 AM

Die Zeitkomplexität misst die Ausführungszeit eines Algorithmus im Verhältnis zur Größe der Eingabe. Zu den Tipps zur Reduzierung der Zeitkomplexität von C++-Programmen gehören: Auswahl geeigneter Container (z. B. Vektor, Liste) zur Optimierung der Datenspeicherung und -verwaltung. Nutzen Sie effiziente Algorithmen wie die schnelle Sortierung, um die Rechenzeit zu verkürzen. Eliminieren Sie mehrere Vorgänge, um Doppelzählungen zu reduzieren. Verwenden Sie bedingte Verzweigungen, um unnötige Berechnungen zu vermeiden. Optimieren Sie die lineare Suche, indem Sie schnellere Algorithmen wie die binäre Suche verwenden.

Entschlüsselung von Laravel-Leistungsengpässen: Optimierungstechniken vollständig enthüllt! Entschlüsselung von Laravel-Leistungsengpässen: Optimierungstechniken vollständig enthüllt! Mar 06, 2024 pm 02:33 PM

Entschlüsselung von Laravel-Leistungsengpässen: Optimierungstechniken vollständig enthüllt! Als beliebtes PHP-Framework bietet Laravel Entwicklern umfangreiche Funktionen und ein komfortables Entwicklungserlebnis. Mit zunehmender Größe des Projekts und steigender Anzahl an Besuchen kann es jedoch zu Leistungsengpässen kommen. Dieser Artikel befasst sich mit den Techniken zur Leistungsoptimierung von Laravel, um Entwicklern dabei zu helfen, potenzielle Leistungsprobleme zu erkennen und zu lösen. 1. Optimierung der Datenbankabfrage mithilfe von Eloquent. Vermeiden Sie verzögertes Laden, wenn Sie Eloquent zum Abfragen der Datenbank verwenden

Laravel-Leistungsengpass aufgedeckt: Optimierungslösung aufgedeckt! Laravel-Leistungsengpass aufgedeckt: Optimierungslösung aufgedeckt! Mar 07, 2024 pm 01:30 PM

Laravel-Leistungsengpass aufgedeckt: Optimierungslösung aufgedeckt! Mit der Entwicklung der Internettechnologie ist die Leistungsoptimierung von Websites und Anwendungen immer wichtiger geworden. Als beliebtes PHP-Framework kann es bei Laravel während des Entwicklungsprozesses zu Leistungsengpässen kommen. In diesem Artikel werden die Leistungsprobleme untersucht, auf die Laravel-Anwendungen stoßen können, und einige Optimierungslösungen und spezifische Codebeispiele bereitgestellt, damit Entwickler diese Probleme besser lösen können. 1. Optimierung von Datenbankabfragen Datenbankabfragen sind einer der häufigsten Leistungsengpässe in Webanwendungen. existieren

So optimieren Sie die Startelemente des WIN7-Systems So optimieren Sie die Startelemente des WIN7-Systems Mar 26, 2024 pm 06:20 PM

1. Drücken Sie die Tastenkombination (Win-Taste + R) auf dem Desktop, um das Ausführungsfenster zu öffnen, geben Sie dann [regedit] ein und drücken Sie zur Bestätigung die Eingabetaste. 2. Nachdem wir den Registrierungseditor geöffnet haben, klicken wir zum Erweitern auf [HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorer] und prüfen dann, ob sich im Verzeichnis ein Serialize-Element befindet. Wenn nicht, können wir mit der rechten Maustaste auf Explorer klicken, ein neues Element erstellen und es Serialize nennen. 3. Klicken Sie dann auf „Serialisieren“, klicken Sie dann mit der rechten Maustaste auf die leere Stelle im rechten Bereich, erstellen Sie einen neuen DWORD-Wert (32) und nennen Sie ihn „Star“.

Die Parameterkonfiguration des Vivox100 wurde enthüllt: Wie kann die Prozessorleistung optimiert werden? Die Parameterkonfiguration des Vivox100 wurde enthüllt: Wie kann die Prozessorleistung optimiert werden? Mar 24, 2024 am 10:27 AM

Die Parameterkonfiguration des Vivox100 wurde enthüllt: Wie kann die Prozessorleistung optimiert werden? In der heutigen Zeit der rasanten technologischen Entwicklung sind Smartphones zu einem unverzichtbaren Bestandteil unseres täglichen Lebens geworden. Als wichtiger Bestandteil eines Smartphones steht die Leistungsoptimierung des Prozessors in direktem Zusammenhang mit der Benutzererfahrung des Mobiltelefons. Als hochkarätiges Smartphone hat die Parameterkonfiguration des Vivox100 große Aufmerksamkeit erregt, insbesondere die Optimierung der Prozessorleistung hat bei den Benutzern große Aufmerksamkeit erregt. Als „Gehirn“ des Mobiltelefons beeinflusst der Prozessor direkt die Laufgeschwindigkeit des Mobiltelefons.

Welche Möglichkeiten gibt es, Ineffizienzen in PHP-Funktionen zu beheben? Welche Möglichkeiten gibt es, Ineffizienzen in PHP-Funktionen zu beheben? May 02, 2024 pm 01:48 PM

Fünf Möglichkeiten zur Optimierung der PHP-Funktionseffizienz: Vermeiden Sie unnötiges Kopieren von Variablen. Verwenden Sie Referenzen, um das Kopieren von Variablen zu vermeiden. Vermeiden Sie wiederholte Funktionsaufrufe. Einfache Inline-Funktionen. Schleifen mithilfe von Arrays optimieren.

See all articles