Heim > Artikel > Web-Frontend > Javascript: Promise Complete Guide
Promise ist eine neue Lösung für die asynchrone Programmierung. ES6 hat es in den Sprachstandard integriert, seine Verwendung vereinheitlicht und das Promise-Objekt nativ bereitgestellt.
Seine Einführung hat das Dilemma der asynchronen Programmierung erheblich verbessert und die Callback-Hölle vermieden. Es ist sinnvoller und leistungsfähiger als herkömmliche Lösungen wie Rückruffunktionen und Ereignisse.
Ein Promise ist, einfach ausgedrückt, ein Konstruktor, der das Ergebnis eines Ereignisses enthält, das in der Zukunft abgeschlossen wird (normalerweise ein asynchroner Vorgang). Syntaktisch gesehen ist ein Promise ein Objekt, von dem Nachrichten zu asynchronen Vorgängen abgerufen werden können. Promise bietet eine einheitliche API, die es ermöglicht, verschiedene asynchrone Vorgänge auf die gleiche Weise abzuwickeln.
Es kann das Callback-Höllenproblem in ES5 effektiv lösen (und tief verschachtelte Callback-Funktionen vermeiden).
Es folgt einem einheitlichen Standard mit prägnanter Syntax, guter Lesbarkeit und Wartbarkeit.
Das Promise-Objekt bietet eine einfache API, die die Verwaltung asynchroner Aufgaben bequemer und flexibler macht.
Wenn wir ein Versprechen verwenden, können wir es in drei Zustände einteilen:
ausstehend: Ausstehend. Dies ist der Ausgangszustand, in dem das Versprechen weder erfüllt noch abgelehnt wird.
erfüllt: Erfüllt/Gelöst/Erfolgreich. Wenn „resolve()“ ausgeführt wird, wechselt das Promise sofort in diesen Zustand und zeigt an, dass es gelöst und die Aufgabe erfolgreich abgeschlossen wurde.
abgelehnt: Abgelehnt/fehlgeschlagen. Wenn „reject()“ ausgeführt wird, wechselt das Promise sofort in diesen Zustand und zeigt damit an, dass es abgelehnt wurde und die Aufgabe fehlgeschlagen ist.
Wenn new Promise() ausgeführt wird, wird der Status des Promise-Objekts auf „Ausstehend“ initialisiert, was seinem Anfangsstatus entspricht. Der Inhalt in den Klammern der neuen Promise()-Zeile wird synchron ausgeführt. Innerhalb der Klammern können Sie eine Funktion für eine asynchrone Aufgabe definieren, die zwei Parameter hat: Auflösung und Ablehnung. Zum Beispiel:
// Create a new promise const promise = new Promise((resolve, reject) => { //promise's state is pending as soon as entering the function console.log('Synchronous Operations'); //Begin to execute asynchronous operations if (Success) { console.log('success'); // If successful, execute resolve() to switch the promise's state to Fulfilled resolve(Success); } else { // If failed, excecute reject() to pass the error and switch the state to Rejected reject(Failure); } }); console.log('LukeW'); //Execute promise's then():to manage success and failure situations promise.then( successValue => { // Process promise's fulfilled state console.log(successValue, 'successfully callback'); // The successMsg here is the Success in resolve(Success) }, errorMsg => { //Process promise's rejected state console.log(errorMsg, 'rejected'); // The errorMsg here is the Failure in reject(Failure) } );
Der Promise-Konstruktor verwendet eine Funktion als Parameter, die zwei Argumente hat: Auflösung und Ablehnung.
const promise = new Promise((resolve, reject) => { // ... some code if (/* Success */){ resolve(value); } else { reject(error); } });
Der Rückgabewert von Promise.resolve(value) ist ebenfalls ein Promise-Objekt, das mit einem .then-Aufruf verkettet werden kann. Der Code lautet wie folgt:
Promise.resolve(11).then(function(value){ console.log(value); // print 11 });
Im Code „resolve(11)“ wird bewirkt, dass das Promise-Objekt in den aufgelösten Zustand übergeht und das Argument 11 an die im nachfolgenden .then angegebene onFulfilled-Funktion übergeben wird. Ein Promise-Objekt kann mit der neuen Promise-Syntax oder mithilfe von Promise.resolve(value) erstellt werden.
function testPromise(ready) { return new Promise(function(resolve,reject){ if(ready) { resolve("hello world"); }else { reject("No thanks"); } }); }; testPromise(true).then(function(msg){ console.log(msg); },function(error){ console.log(error); });
Die Bedeutung des obigen Codes besteht darin, ein Argument an die testPromise-Methode zu übergeben, die ein Promise-Objekt zurückgibt. Wenn das Argument wahr ist, wird die Methode „resolve()“ des Promise-Objekts aufgerufen und der an sie übergebene Parameter wird dann an die erste Funktion im nachfolgenden .then übergeben, was zur Ausgabe „Hallo Welt“ führt. Wenn das Argument falsch ist, wird die Methode „reject()“ des Promise-Objekts aufgerufen, die die zweite Funktion in .then auslöst und zur Ausgabe „Nein, danke“ führt.
Die then-Methode kann zwei Callback-Funktionen als Parameter akzeptieren. Die erste Rückruffunktion wird aufgerufen, wenn sich der Status des Promise-Objekts in „Aufgelöst“ ändert, und die zweite Rückruffunktion wird aufgerufen, wenn sich der Status des Promise-Objekts in „Abgelehnt“ ändert. Der zweite Parameter ist optional und kann weggelassen werden.
Die then-Methode gibt eine neue Promise-Instanz zurück (nicht die ursprüngliche Promise-Instanz). Daher kann eine verkettete Syntax verwendet werden, bei der nach der ersten eine weitere then-Methode aufgerufen wird.
Wenn Sie asynchrone Ereignisse nacheinander schreiben müssen, sodass sie seriell ausgeführt werden müssen, können Sie sie wie folgt schreiben:
let promise = new Promise((resolve,reject)=>{ ajax('first').success(function(res){ resolve(res); }) }) promise.then(res=>{ return new Promise((resovle,reject)=>{ ajax('second').success(function(res){ resolve(res) }) }) }).then(res=>{ return new Promise((resovle,reject)=>{ ajax('second').success(function(res){ resolve(res) }) }) }).then(res=>{ })
Zusätzlich zur Then-Methode verfügt ein Promise-Objekt auch über eine Catch-Methode. Diese Methode entspricht dem zweiten Parameter der then-Methode und zeigt auf die Rückruffunktion zum Zurückweisen. Allerdings hat die Catch-Methode eine zusätzliche Funktion: Wenn beim Ausführen der Resolve-Callback-Funktion ein Fehler auftritt oder eine Ausnahme ausgelöst wird, wird die Ausführung nicht gestoppt. Stattdessen wird die Catch-Methode eingegeben.
p.then((data) => { console.log('resolved',data); },(err) => { console.log('rejected',err); } ); p.then((data) => { console.log('resolved',data); }).catch((err) => { console.log('rejected',err); });
The all method can be used to complete parallel tasks. It takes an array as an argument, where each item in the array is a Promise object. When all the Promises in the array have reached the resolved state, the state of the all method will also become resolved. However, if even one of the Promises changes to rejected, the state of the all method will become rejected.
let promise1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(1); },2000) }); let promise2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(2); },1000) }); let promise3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(3); },3000) }); Promise.all([promise1,promise2,promise3]).then(res=>{ console.log(res); //result:[1,2,3] })
When the all method is called and successfully resolves, the result passed to the callback function is also an array. This array stores the values from each Promise object when their respective resolve functions were executed, in the order they were passed to the all method.
The race method, like all, accepts an array where each item is a Promise. However, unlike all, when the first Promise in the array completes, race immediately returns the value of that Promise. If the first Promise's state becomes resolved, the race method's state will also become resolved; conversely, if the first Promise becomes rejected, the race method's state will become rejected.
let promise1 = new Promise((resolve,reject)=>{ setTimeout(()=>{ reject(1); },2000) }); let promise2 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(2); },1000) }); let promise3 = new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(3); },3000) }); Promise.race([promise1,promise2,promise3]).then(res=>{ console.log(res); //result:2 },rej=>{ console.log(rej)}; )
So, what is the practical use of the race method? When you want to do something, but if it takes too long, you want to stop it; this method can be used to solve that problem:
Promise.race([promise1,timeOutPromise(5000)]).then(res=>{})
The finally method is used to specify an operation that will be executed regardless of the final state of the Promise object. This method was introduced in the ES2018 standard.
promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});
In the code above, regardless of the final state of the promise, after the then or catch callbacks have been executed, the callback function specified by the finally method will be executed.
In work, you often encounter a requirement like this: for example, after sending an A request using AJAX, you need to pass the obtained data to a B request if the first request is successful; you would need to write the code as follows:
let fs = require('fs') fs.readFile('./a.txt','utf8',function(err,data){ fs.readFile(data,'utf8',function(err,data){ fs.readFile(data,'utf8',function(err,data){ console.log(data) }) }) })
The above code has the following drawbacks:
The latter request depends on the success of the previous request, where the data needs to be passed down, leading to multiple nested AJAX requests, making the code less intuitive.
Even if the two requests don't need to pass parameters between them, the latter request still needs to wait for the success of the former before executing the next step. In this case, you also need to write the code as shown above, which makes the code less intuitive.
After the introduction of Promises, the code becomes like this:
let fs = require('fs') function read(url){ return new Promise((resolve,reject)=>{ fs.readFile(url,'utf8',function(error,data){ error && reject(error) resolve(data) }) }) } read('./a.txt').then(data=>{ return read(data) }).then(data=>{ return read(data) }).then(data=>{ console.log(data) })
This way, the code becomes much more concise, solving the problem of callback hell.
Das obige ist der detaillierte Inhalt vonJavascript: Promise Complete Guide. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!