suchen
HeimWeb-Frontendjs-TutorialWie verwende ich Promise in asynchronem JavaScript programming_node.js?1.1.5


Asynchron?

Ich habe das Wort asynchron (asynchron) an vielen Stellen gesehen, aber wenn ich dieses Konzept nicht vollständig verstehe, stelle ich fest, dass ich oft als „bereits klar“ angesehen werde (*  ̄? ̄ ).

Wenn Sie eine ähnliche Situation haben, spielt es keine Rolle. Suchen Sie nach diesem Wort und Sie erhalten eine grobe Erklärung. Hier werde ich die Asynchronität von JavaScript etwas näher erläutern.

Sehen Sie sich diesen Code an:

var start = new Date();
setTimeout(function(){
  var end = new Date();
  console.log("Time elapsed: ", end - start, "ms");
}, 500);
while (new Date - start < 1000) {};

Nachdem Sie diesen Code ausgeführt haben, erhalten Sie ein Ergebnis wie „Zeit verstrichen: 1013 ms“. Die von setTimeout() festgelegte Funktion, die 500 ms in der Zukunft ausgeführt werden soll, wartet tatsächlich mehr als 1000 ms, bevor sie ausgeführt wird.

Wie soll ich es erklären? Wenn setTimeout() aufgerufen wird, wird ein verzögertes Ereignis in die Warteschlange gestellt. Fahren Sie dann mit der Ausführung des Codes danach und des Codes danach fort, bis kein Code mehr vorhanden ist. Wenn kein Code vorhanden ist, wird der JavaScript-Thread inaktiv. Zu diesem Zeitpunkt durchsucht die JavaScript-Ausführungs-Engine die Warteschlange, findet das Ereignis, das in der Warteschlange „ausgelöst werden sollte“ und ruft dann den Handler (die Funktion) dieses Ereignisses auf. Nachdem der Prozessor die Ausführung abgeschlossen hat, kehrt er zur Warteschlange zurück und prüft das nächste Ereignis.

Single-Threaded-JavaScript funktioniert in Form einer Ereignisschleife durch Warteschlangen. Daher wird im vorherigen Code while verwendet, um die Ausführungs-Engine bis zu 1000 ms lang zu ziehen, während der Code ausgeführt wird, und es wird kein Ereignis ausgelöst, bis der gesamte Code abgeschlossen und in die Warteschlange zurückgekehrt ist. Dies ist der asynchrone Mechanismus von JavaScript.
Die Asynchronitätsschwierigkeiten von JavaScript

Asynchrone Vorgänge in JavaScript sind möglicherweise nicht immer einfach.

Ajax ist vielleicht die asynchrone Operation, die wir am häufigsten verwenden. Am Beispiel von jQuery sieht der Code zum Initiieren einer Ajax-Anfrage im Allgemeinen so aus:

// Ajax请求示意代码
$.ajax({
  url: url,
  data: dataObject,
  success: function(){},
  error: function(){}
});

Ist an dieser Schreibweise etwas falsch? Einfach ausgedrückt ist es nicht tragbar genug. Warum müssen wir Erfolgs- und Fehlerrückrufe dort schreiben, wo die Anfrage initiiert wird? Wenn mein Rückruf viele, viele Dinge tun muss, muss ich dann hierher zurücklaufen und Code hinzufügen, wenn mir eine Sache einfällt?

Für ein weiteres Beispiel möchten wir so etwas vervollständigen: Es gibt 4 URL-Adressen für den Ajax-Zugriff. Nachdem der erste Zugriff abgeschlossen ist, müssen wir die erste verwenden Daten erhalten als Der zweite Parameter wird erneut zugegriffen, und dann wird auf den dritten zugegriffen, nachdem der zweite Zugriff abgeschlossen ist ... Von diesem Punkt an sind alle 4 Zugriffe abgeschlossen. Nach dieser Schreibweise scheint es so zu werden:

$.ajax({
  url: url1,
  success: function(data){
    $.ajax({
      url: url2,
      data: data,
      success: function(data){
        $.ajax({
          //...
        });
      }  
    });
  }
})

Sie werden definitiv denken, dass dieser Code namens Pyramid of Doom so aussieht schrecklich. Wenn Sie es gewohnt sind, direkt angehängte Rückrufe zu schreiben, sind Sie möglicherweise verwirrt über die asynchronen Ereignisse, die von einem zum nächsten weitergegeben werden. Das separate Benennen und Speichern dieser Rückruffunktionen kann die Verschachtelung im Formular reduzieren und den Code klarer machen, löst das Problem jedoch immer noch nicht.

Eine weitere häufige Schwierigkeit besteht darin, zwei Ajax-Anfragen gleichzeitig zu senden und dann nach erfolgreicher Rückkehr beider Anfragen die nächste Aktion auszuführen Scheint es etwas schwierig zu sein, der anrufenden Position einen Rückruf zuzuordnen?

Promise eignet sich für den Umgang mit diesen asynchronen Vorgängen und ermöglicht Ihnen das Schreiben eleganterer Codes.
Versprechen kommt auf die Bühne

Was ist Versprechen? Nehmen wir weiterhin den vorherigen jQuery-Ajax-Anforderungssignalcode als Beispiel. Dieser Code kann tatsächlich so geschrieben werden:

var promise = $.ajax({
  url: url,
  data: dataObject
});
promise.done(function(){});
promise.fail(function(){});

Dies ähnelt dem vorherigen Ajax-Anfragesignal. Die Codes sind gleichwertig. Wie Sie sehen, ändert das Hinzufügen von Promise die Form des Codes. Ajax-Anfragen werden genau wie Variablenzuweisungen „gespeichert“. Das ist Kapselung, und die Kapselung wird asynchrone Ereignisse wirklich einfacher machen.
Kapselung ist nützlich

Das Promise-Objekt ist wie eine gekapselte Referenz auf ein asynchrones Ereignis. Möchten Sie nach Abschluss dieses asynchronen Ereignisses etwas unternehmen? Hängen Sie einfach Rückrufe an, egal wie viele Sie anhängen, es spielt keine Rolle!

Die Ajax-Methode von jQuery gibt ein Promise-Objekt zurück (dies ist eine wichtige Funktion, die in jQuery 1.5 hinzugefügt wurde). Wenn ich zwei Funktionen do1() und do2() habe, die ich ausführen möchte, nachdem das asynchrone Ereignis erfolgreich abgeschlossen wurde, muss ich nur Folgendes tun:

promise.done(do1);
// Other code here.
promise.done(do2);

Auf diese Weise ist es viel freier. Ich muss lediglich dieses Promise-Objekt speichern und jederzeit eine beliebige Anzahl von Rückrufen daran anhängen, während ich Code schreibe, unabhängig davon, wo das asynchrone Ereignis initiiert wird. Dies ist der Vorteil von Promise.
Formale Einführung

Promise ist für asynchrone Operationen so nützlich, dass es zu einer Spezifikation von CommonJS namens Promises/A entwickelt wurde. Promise stellt den Rückgabewert nach Abschluss einer Operation dar. Es hat drei Zustände:

  1. Positiv (erfüllt oder gelöst), was angibt, dass die Promise-Operation erfolgreich war.

  2. Eine Verneinung (abgelehnt oder fehlgeschlagen) zeigt an, dass der Promise-Vorgang fehlgeschlagen ist.

  3. Warten (ausstehend), es wurde noch kein positives oder negatives Ergebnis erzielt, in Bearbeitung.

Darüber hinaus gibt es einen nominalen Zustand, der angibt, ob die Promise-Operation erfolgreich war oder fehlgeschlagen ist. Dabei handelt es sich um eine Sammlung positiver und negativer Zustände, die als „abgewickelt“ bezeichnet werden. Promise verfügt außerdem über die folgenden wichtigen Funktionen:

  •     一个Promise只能从等待状态转变为肯定或否定状态一次,一旦转变为肯定或否定状态,就再也不会改变状态。

  •     如果在一个Promise结束(成功或失败,同前面的说明)后,添加针对成功或失败的回调,则回调函数会立即执行。

想想Ajax操作,发起一个请求后,等待着,然后成功收到返回或出现错误(失败)。这是否和Promise相当一致?

进一步解释Promise的特性还有一个很好的例子:jQuery的$(document).ready(onReady)。其中onReady回调函数会在DOM就绪后执行,但有趣的是,如果在执行到这句代码之前,DOM就已经就绪了,那么onReady会立即执行,没有任何延迟(也就是说,是同步的)。
Promise示例
生成Promise

Promises/A里列出了一系列实现了Promise的JavaScript库,jQuery也在其中。下面是用jQuery生成Promise的代码:

var deferred = $.Deferred();
deferred.done(function(message){console.log("Done: " + message)});
deferred.resolve("morin"); // Done: morin

jQuery自己特意定义了名为Deferred的类,它实际上就是Promise。$.Deferred()方法会返回一个新生成的Promise实例。一方面,使用deferred.done()、deferred.fail()等为它附加回调,另一方面,调用deferred.resolve()或deferred.reject()来肯定或否定这个Promise,且可以向回调传递任意数据。
合并Promise

还记得我前文说的同时发送2个Ajax请求的难题吗?继续以jQuery为例,Promise将可以这样解决它:

var promise1 = $.ajax(url1),
promise2 = $.ajax(url2),
promiseCombined = $.when(promise1, promise2);
promiseCombined.done(onDone);

$.when()方法可以合并多个Promise得到一个新的Promise,相当于在原多个Promise之间建立了AND(逻辑与)的关系,如果所有组成Promise都已成功,则令合并后的Promise也成功,如果有任意一个组成Promise失败,则立即令合并后的Promise失败。
级联Promise

再继续我前文的依次执行一系列异步任务的问题。它将用到Promise最为重要的.then()方法(在Promises/A规范中,也是用“有then()方法的对象”来定义Promise的)。代码如下:

var promise = $.ajax(url1);
promise = promise.then(function(data){
  return $.ajax(url2, data);
});
promise = promise.then(function(data){
  return $.ajax(url3, data);
});
// ...

Promise的.then()方法的完整形式是.then(onDone, onFail, onProgress),这样看上去,它像是一个一次性就可以把各种回调都附加上去的简便方法(.done()、.fail()可以不用了)。没错,你的确可以这样使用,这是等效的。

但.then()方法还有它更为有用的功能。如同then这个单词本身的意义那样,它用来清晰地指明异步事件的前后关系:“先这个,然后(then)再那个”。这称为Promise的级联。

要级联Promise,需要注意的是,在传递给then()的回调函数中,一定要返回你想要的代表下一步任务的Promise(如上面代码的$.ajax(url2, data))。这样,前面被赋值的那个变量才会变成新的Promise。而如果then()的回调函数返回的不是Promise,则then()方法会返回最初的那个Promise。

应该会觉得有些难理解?从代码执行的角度上说,上面这段带有多个then()的代码其实还是被JavaScript引擎运行一遍就结束。但它就像是写好的舞台剧的剧本一样,读过一遍后,JavaScript引擎就会在未来的时刻,依次安排演员按照剧本来演出,而演出都是异步的。then()方法就是让你能写出异步剧本的笔。
将Promise用在基于回调函数的API

前文反复用到的$.ajax()方法会返回一个Promise对象,这其实只是jQuery特意提供的福利。实际情况是,大多数JavaScript API,包括Node.js中的原生函数,都基于回调函数,而不是基于Promise。这种情况下使用Promise会需要自行做一些加工。

这个加工其实比较简单和直接,下面是例子:

var deferred = $.Deferred();
setTimeout(deferred.resolve, 1000);
deferred.done(onDone);

这样,将Promise的肯定或否定的触发器,作为API的回调传入,就变成了Promise的处理模式了。
Promise是怎么实现出来的?

本文写Promise写到这里,你发现了全都是基于已有的实现了Promise的库。那么,如果要自行构筑一个Promise的话呢?

位列于Promises/A的库列表第一位的Q可以算是最符合Promises/A规范且相当直观的实现。如果你想了解如何做出一个Promise,可以参考Q提供的设计模式解析。

限于篇幅,本文只介绍Promise的应用。我会在以后单独开一篇文章来详述Promise的实现细节。

作为JavaScript后续版本的ECMAScript 6将原生提供Promise,如果你想知道它的用法,推荐阅读JavaScript Promises: There and back again。
结语

Das Wort „Versprechen“ ist so hartnäckig, dass es nicht zur Übersetzung geeignet ist und die Bedeutung auf den ersten Blick unklar ist. Es kann jedoch tatsächlich eine erhebliche Hilfe bei der Ausführung komplexerer asynchroner Aufgaben in JavaScript sein.

Das Obige ist der Inhalt der Promise-Nutzung in der asynchronen JavaScript-Programmierung_node.js?1.1.5. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Stellungnahme
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
JavaScript -Engines: Implementierungen vergleichenJavaScript -Engines: Implementierungen vergleichenApr 13, 2025 am 12:05 AM

Unterschiedliche JavaScript -Motoren haben unterschiedliche Auswirkungen beim Analysieren und Ausführen von JavaScript -Code, da sich die Implementierungsprinzipien und Optimierungsstrategien jeder Engine unterscheiden. 1. Lexikalanalyse: Quellcode in die lexikalische Einheit umwandeln. 2. Grammatikanalyse: Erzeugen Sie einen abstrakten Syntaxbaum. 3. Optimierung und Kompilierung: Generieren Sie den Maschinencode über den JIT -Compiler. 4. Führen Sie aus: Führen Sie den Maschinencode aus. V8 Engine optimiert durch sofortige Kompilierung und versteckte Klasse.

Jenseits des Browsers: JavaScript in der realen WeltJenseits des Browsers: JavaScript in der realen WeltApr 12, 2025 am 12:06 AM

Zu den Anwendungen von JavaScript in der realen Welt gehören die serverseitige Programmierung, die Entwicklung mobiler Anwendungen und das Internet der Dinge. Die serverseitige Programmierung wird über node.js realisiert, die für die hohe gleichzeitige Anfrageverarbeitung geeignet sind. 2. Die Entwicklung der mobilen Anwendungen erfolgt durch reaktnative und unterstützt die plattformübergreifende Bereitstellung. 3.. Wird für die Steuerung von IoT-Geräten über die Johnny-Five-Bibliothek verwendet, geeignet für Hardware-Interaktion.

Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)Erstellen einer SaaS-Anwendung mit mehreren Mietern mit Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

Ich habe eine funktionale SaaS-Anwendung mit mehreren Mandanten (eine EdTech-App) mit Ihrem täglichen Tech-Tool erstellt und Sie können dasselbe tun. Was ist eine SaaS-Anwendung mit mehreren Mietern? Mit Multi-Tenant-SaaS-Anwendungen können Sie mehrere Kunden aus einem Sing bedienen

So erstellen Sie eine SaaS-Anwendung mit mehreren Mietern mit Next.js (Frontend Integration)So erstellen Sie eine SaaS-Anwendung mit mehreren Mietern mit Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

Dieser Artikel zeigt die Frontend -Integration mit einem Backend, das durch die Genehmigung gesichert ist und eine funktionale edtech SaaS -Anwendung unter Verwendung von Next.js. erstellt. Die Frontend erfasst Benutzerberechtigungen zur Steuerung der UI-Sichtbarkeit und stellt sicher, dass API-Anfragen die Rollenbasis einhalten

JavaScript: Erforschung der Vielseitigkeit einer WebspracheJavaScript: Erforschung der Vielseitigkeit einer WebspracheApr 11, 2025 am 12:01 AM

JavaScript ist die Kernsprache der modernen Webentwicklung und wird für seine Vielfalt und Flexibilität häufig verwendet. 1) Front-End-Entwicklung: Erstellen Sie dynamische Webseiten und einseitige Anwendungen durch DOM-Operationen und moderne Rahmenbedingungen (wie React, Vue.js, Angular). 2) Serverseitige Entwicklung: Node.js verwendet ein nicht blockierendes E/A-Modell, um hohe Parallelitäts- und Echtzeitanwendungen zu verarbeiten. 3) Entwicklung von Mobil- und Desktop-Anwendungen: Die plattformübergreifende Entwicklung wird durch reaktnative und elektronen zur Verbesserung der Entwicklungseffizienz realisiert.

Die Entwicklung von JavaScript: Aktuelle Trends und ZukunftsaussichtenDie Entwicklung von JavaScript: Aktuelle Trends und ZukunftsaussichtenApr 10, 2025 am 09:33 AM

Zu den neuesten Trends im JavaScript gehören der Aufstieg von Typenkripten, die Popularität moderner Frameworks und Bibliotheken und die Anwendung der WebAssembly. Zukunftsaussichten umfassen leistungsfähigere Typsysteme, die Entwicklung des serverseitigen JavaScript, die Erweiterung der künstlichen Intelligenz und des maschinellen Lernens sowie das Potenzial von IoT und Edge Computing.

Entmystifizieren JavaScript: Was es tut und warum es wichtig istEntmystifizieren JavaScript: Was es tut und warum es wichtig istApr 09, 2025 am 12:07 AM

JavaScript ist der Eckpfeiler der modernen Webentwicklung. Zu den Hauptfunktionen gehören eine ereignisorientierte Programmierung, die Erzeugung der dynamischen Inhalte und die asynchrone Programmierung. 1) Ereignisgesteuerte Programmierung ermöglicht es Webseiten, sich dynamisch entsprechend den Benutzeroperationen zu ändern. 2) Die dynamische Inhaltsgenerierung ermöglicht die Anpassung der Seiteninhalte gemäß den Bedingungen. 3) Asynchrone Programmierung stellt sicher, dass die Benutzeroberfläche nicht blockiert ist. JavaScript wird häufig in der Webinteraktion, der einseitigen Anwendung und der serverseitigen Entwicklung verwendet, wodurch die Flexibilität der Benutzererfahrung und die plattformübergreifende Entwicklung erheblich verbessert wird.

Ist Python oder JavaScript besser?Ist Python oder JavaScript besser?Apr 06, 2025 am 12:14 AM

Python eignet sich besser für Datenwissenschaft und maschinelles Lernen, während JavaScript besser für die Entwicklung von Front-End- und Vollstapel geeignet ist. 1. Python ist bekannt für seine prägnante Syntax- und Rich -Bibliotheks -Ökosystems und ist für die Datenanalyse und die Webentwicklung geeignet. 2. JavaScript ist der Kern der Front-End-Entwicklung. Node.js unterstützt die serverseitige Programmierung und eignet sich für die Entwicklung der Vollstapel.

See all articles

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 vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

MinGW – Minimalistisches GNU für Windows

MinGW – Minimalistisches GNU für Windows

Dieses Projekt wird derzeit auf osdn.net/projects/mingw migriert. Sie können uns dort weiterhin folgen. MinGW: Eine native Windows-Portierung der GNU Compiler Collection (GCC), frei verteilbare Importbibliotheken und Header-Dateien zum Erstellen nativer Windows-Anwendungen, einschließlich Erweiterungen der MSVC-Laufzeit zur Unterstützung der C99-Funktionalität. Die gesamte MinGW-Software kann auf 64-Bit-Windows-Plattformen ausgeführt werden.

WebStorm-Mac-Version

WebStorm-Mac-Version

Nützliche JavaScript-Entwicklungstools

SecLists

SecLists

SecLists ist der ultimative Begleiter für Sicherheitstester. Dabei handelt es sich um eine Sammlung verschiedener Arten von Listen, die häufig bei Sicherheitsbewertungen verwendet werden, an einem Ort. SecLists trägt dazu bei, Sicherheitstests effizienter und produktiver zu gestalten, indem es bequem alle Listen bereitstellt, die ein Sicherheitstester benötigen könnte. Zu den Listentypen gehören Benutzernamen, Passwörter, URLs, Fuzzing-Payloads, Muster für vertrauliche Daten, Web-Shells und mehr. Der Tester kann dieses Repository einfach auf einen neuen Testcomputer übertragen und hat dann Zugriff auf alle Arten von Listen, die er benötigt.

Dreamweaver Mac

Dreamweaver Mac

Visuelle Webentwicklungstools

Sicherer Prüfungsbrowser

Sicherer Prüfungsbrowser

Safe Exam Browser ist eine sichere Browserumgebung für die sichere Teilnahme an Online-Prüfungen. Diese Software verwandelt jeden Computer in einen sicheren Arbeitsplatz. Es kontrolliert den Zugriff auf alle Dienstprogramme und verhindert, dass Schüler nicht autorisierte Ressourcen nutzen.