| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Promise | [Back] [Original] |
Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.
Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit Juli 2015 browserbergreifend verfgbar.
* Einige Teile dieser Funktion werden mglicherweise unterschiedlich gut untersttzt.
Das Promise-Objekt reprsentiert den eventuellen Abschluss (oder Fehlschlag) einer asynchronen Operation und ihren resultierenden Wert.
Um zu erfahren, wie Promises funktionieren und wie Sie sie verwenden knnen, empfehlen wir Ihnen, zunchst Using promises zu lesen.
Ein Promise ist ein Proxy fr einen Wert, der beim Erstellen des Promise nicht unbedingt bekannt ist. Es ermglicht Ihnen, Handler mit dem eventuellen Erfolgswert oder Fehlergrund einer asynchronen Aktion zu verknpfen. Dadurch knnen asynchrone Methoden Werte wie synchrone Methoden zurckgeben: Statt den endgltigen Wert sofort zurckzugeben, gibt die asynchrone Methode ein Promise zurck, das den Wert zu einem Zeitpunkt in der Zukunft bereitstellt.
Ein Promise befindet sich in einem dieser Zustnde:
Der eventuelle Zustand eines ausstehenden Promise kann entweder mit einem Wert fulfilled oder mit einem Grund (Fehler) rejected sein.
Wenn eine dieser Optionen eintritt, werden die zugehrigen Handler aufgerufen, die durch die then-Methode eines Promise in die Warteschlange gestellt wurden. Falls das Promise bereits erfllt oder abgelehnt wurde, wenn ein entsprechender Handler angehngt wird, wird der Handler aufgerufen. Daher besteht keine Race Condition zwischen dem Abschluss einer asynchronen Operation und dem Anhngen ihrer Handler.
Ein Promise wird als settled bezeichnet, wenn es entweder erfllt oder abgelehnt ist, aber nicht ausstehend.
Im Zusammenhang mit Promises werden Sie auch den Begriff resolved hren das bedeutet, dass das Promise settled ist oder darauf festgelegt wurde, dem eventuellen Zustand eines anderen Promise zu entsprechen, und ein weiteres Auflsen oder Ablehnen keine Wirkung hat. Das Dokument States and fates aus dem ursprnglichen Promise-Vorschlag enthlt weitere Einzelheiten zur Promise-Terminologie. Umgangssprachlich sind resolved Promises oft gleichbedeutend mit fulfilled Promises, aber wie in States and fates dargestellt, knnen resolved Promises auch pending oder rejected sein. Zum Beispiel:
new Promise((resolveOuter) => {
resolveOuter(
new Promise((resolveInner) => {
setTimeout(resolveInner, 1000);
}),
);
});
Dieses Promise ist bereits zum Zeitpunkt seiner Erstellung resolved (weil resolveOuter synchron aufgerufen wird), es wird jedoch mit einem anderen Promise aufgelst und ist daher erst 1 Sekunde spter fulfilled, wenn das innere Promise erfllt wird. In der Praxis erfolgt die Auflsung hufig im Hintergrund und ist nicht beobachtbar; nur ihre Erfllung oder Ablehnung ist es.
Hinweis:
Mehrere andere Sprachen verfgen ber Mechanismen zur verzgerten Auswertung und zum Aufschieben einer Berechnung, die sie ebenfalls Promises nennen, beispielsweise Scheme. Promises in JavaScript reprsentieren Prozesse, die bereits stattfinden und mit Callback-Funktionen verkettet werden knnen. Wenn Sie einen Ausdruck verzgert auswerten mchten, sollten Sie eine Funktion ohne Argumente verwenden, z. B. f = () => expression, um den verzgert ausgewerteten Ausdruck zu erstellen, und f(), um den Ausdruck sofort auszuwerten.
Promise selbst verfgt ber kein erstklassiges Protokoll zur Abbruchsteuerung, aber mglicherweise knnen Sie die zugrunde liegende asynchrone Operation direkt abbrechen, blicherweise mit AbortController.
Die Promise-Methoden then(), catch() und finally() werden verwendet, um weitere Aktionen mit einem Promise zu verknpfen, das settled wird. Die Methode then() akzeptiert bis zu zwei Argumente; das erste Argument ist eine Callback-Funktion fr den erfllten Fall des Promise, und das zweite Argument ist eine Callback-Funktion fr den abgelehnten Fall. Die Methoden catch() und finally() rufen intern then() auf und machen die Fehlerbehandlung weniger ausfhrlich. Ein catch() ist beispielsweise eigentlich nur ein then(), bei dem kein Erfllungs-Handler bergeben wird. Da diese Methoden Promises zurckgeben, knnen sie verkettet werden. Zum Beispiel:
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 300);
});
myPromise
.then(handleFulfilledA, handleRejectedA)
.then(handleFulfilledB, handleRejectedB)
.then(handleFulfilledC, handleRejectedC);
Wir verwenden die folgende Terminologie: initial promise ist das Promise, auf dem then aufgerufen wird; new promise ist das von then zurckgegebene Promise. Die beiden an then bergebenen Callbacks werden jeweils fulfillment handler und rejection handler genannt.
Der settled Zustand des initialen Promise bestimmt, welcher Handler ausgefhrt wird.
Der Abschluss des Handlers bestimmt den settled Zustand des neuen Promise.
Wenn beispielsweise im obigen Code myPromise abgelehnt wird, wird handleRejectedA aufgerufen. Wenn handleRejectedA normal abgeschlossen wird (ohne zu werfen oder ein abgelehntes Promise zurckzugeben), wird das vom ersten then zurckgegebene Promise erfllt, anstatt abgelehnt zu bleiben. Wenn ein Fehler daher sofort behandelt werden muss, wir aber den Fehlerzustand in der Kette beibehalten mchten, mssen wir im rejection handler einen Fehler irgendeines Typs werfen. Wenn hingegen keine unmittelbare Notwendigkeit besteht, knnen wir die Fehlerbehandlung bis zum abschlieenden catch()-Handler weglassen.
myPromise
.then(handleFulfilledA)
.then(handleFulfilledB)
.then(handleFulfilledC)
.catch(handleRejectedAny);
Bei Verwendung von arrow functions fr die Callback-Funktionen knnte die Implementierung der Promise-Kette etwa so aussehen:
myPromise
.then((value) => `${value} and bar`)
.then((value) => `${value} and bar again`)
.then((value) => `${value} and again`)
.then((value) => `${value} and again`)
.then((value) => {
console.log(value);
})
.catch((err) => {
console.error(err);
});
Hinweis: Fr eine schnellere Ausfhrung sollten alle synchronen Aktionen vorzugsweise innerhalb eines Handlers ausgefhrt werden, da andernfalls mehrere Ticks bentigt wrden, um alle Handler nacheinander auszufhren.
JavaScript verwaltet eine Job-Warteschlange. JavaScript entnimmt jeweils einen Job aus der Warteschlange und fhrt ihn bis zum Abschluss aus. Die Jobs werden durch den Executor des Promise()-Konstruktors, die an then bergebenen Handler oder eine Plattform-API definiert, die ein Promise zurckgibt. Die Promises in einer Kette reprsentieren die Abhngigkeitsbeziehung zwischen diesen Jobs. Wenn ein Promise settled wird, werden die jeweiligen damit verknpften Handler am Ende der Job-Warteschlange hinzugefgt.
Ein Promise kann an mehr als einer Kette teilnehmen. Beim folgenden Code fhrt die Erfllung von promiseA dazu, dass sowohl handleFulfilled1 als auch handleFulfilled2 zur Job-Warteschlange hinzugefgt werden. Da handleFulfilled1 zuerst registriert wird, wird es auch zuerst aufgerufen.
const promiseA = new Promise(myExecutorFunc);
const promiseB = promiseA.then(handleFulfilled1, handleRejected1);
const promiseC = promiseA.then(handleFulfilled2, handleRejected2);
Eine Aktion kann einem bereits settled Promise zugewiesen werden. In diesem Fall wird die Aktion sofort am Ende der Job-Warteschlange hinzugefgt und ausgefhrt, wenn alle bestehenden Jobs abgeschlossen sind. Daher findet eine Aktion fr ein bereits settled Promise erst statt, nachdem der aktuelle synchrone Code abgeschlossen ist und mindestens ein Loop-Tick vergangen ist. Dies garantiert, dass Promise-Aktionen asynchron sind.
const promiseA = new Promise((resolve, reject) => {
resolve(777);
});
// At this point, "promiseA" is already settled.
promiseA.then((val) => console.log("asynchronous logging has val:", val));
console.log("immediate logging");
// produces output in this order:
// immediate logging
// asynchronous logging has val: 777
Das JavaScript-kosystem verfgte ber mehrere Promise-Implementierungen, lange bevor Promises Teil der Sprache wurden. Obwohl sie intern unterschiedlich dargestellt werden, implementieren alle Promise-hnlichen Objekte zumindest die Thenable-Schnittstelle. Ein thenable implementiert die Methode .then(), die mit zwei Callbacks aufgerufen wird: einer fr den Fall, dass das Promise erfllt wird, und einer fr den Fall, dass es abgelehnt wird. Promises sind ebenfalls thenables.
Um mit den bestehenden Promise-Implementierungen zusammenzuarbeiten, erlaubt die Sprache die Verwendung von thenables anstelle von Promises. Beispielsweise lst Promise.resolve nicht nur Promises auf, sondern verfolgt auch thenables.
// This is not a Promises/A+ compliant thenable! It calls onFulfilled
// synchronously. For demonstration only.
const thenable = {
then(onFulfilled, onRejected) {
onFulfilled({
// The thenable is fulfilled with another thenable
then(onFulfilled, onRejected) {
onFulfilled(42);
},
});
},
};
Promise.resolve(thenable); // A promise fulfilled with 42
Die Methode then() ist dafr verantwortlich, die Ausfhrung der bereitgestellten Callbacks onFulfilled und onRejected zu planen. Ihre Semantik, einschlielich Fehlerbehandlung und Asynchronitt, ist in der Promises/A+-Spezifikation przise definiert und wird hier nicht wiederholt. Es kommt sehr selten vor, dass Sie selbst ein thenable implementieren mssen; selbst wenn Sie keine nativen Promises verwenden, wrden Sie wahrscheinlich eine Promise-Bibliothek wie Bluebird verwenden.
Die Klasse Promise bietet vier zentrale statische Methoden, um die Concurrency asynchroner Aufgaben zu erleichtern:
Promise.all()Wird erfllt, wenn alle Promises erfllt werden; wird abgelehnt, wenn eines der Promises abgelehnt wird.
Promise.allSettled()Wird erfllt, wenn alle Promises settled werden.
Promise.any()Wird erfllt, wenn eines der Promises erfllt wird; wird abgelehnt, wenn alle Promises abgelehnt werden.
Promise.race()Wird settled, wenn eines der Promises settled wird. Anders ausgedrckt: Es wird erfllt, wenn eines der Promises erfllt wird; es wird abgelehnt, wenn eines der Promises abgelehnt wird.
Alle diese Methoden akzeptieren ein iterable von Promises (genauer gesagt thenables) und geben ein neues Promise zurck. Sie untersttzen alle Subclassing, was bedeutet, dass sie auf Unterklassen von Promise aufgerufen werden knnen und das Ergebnis ein Promise des Unterklassentyps ist. Dafr muss der Konstruktor der Unterklasse dieselbe Signatur wie der Konstruktor Promise() implementieren er akzeptiert eine einzelne executor-Funktion, die mit den Callbacks resolve und reject als Parametern aufgerufen werden kann. Die Unterklasse muss auerdem ber eine statische Methode resolve verfgen, die wie Promise.resolve() aufgerufen werden kann, um Werte zu Promises aufzulsen.
Es gibt zwei weitere praktische statische Methoden: Promise.allKeyed() und Promise.allSettledKeyed(). Sie verhalten sich wie Promise.all() und Promise.allSettled(), akzeptieren jedoch Objekte von Promises und geben Promises zurck, die mit Objekten derselben Form erfllt werden. Durch die Arbeit mit Objekten statt Arrays knnen Sie Ergebnisse mit semantisch aussagekrftigen Schlsseln verknpfen, anstatt mit einer beliebigen Array-Reihenfolge, die schwierig zu pflegen sein kann.
Diese Methoden hngen mithilfe von then() Handler an jedes Eingabe-Promise an. Selbst wenn das resultierende Promise frhzeitig settled wird (etwa wenn eine Eingabe in Promise.race() settled wird), werden die anderen Handler nicht entfernt. Die wiederholte bergabe desselben ausstehenden Promise an Concurrency-Methoden kann Handler ansammeln, selbst wenn diese Handler niemals verwendet werden:
const pendingPromise = new Promise(() => {});
for (let i = 0; i < 1000; i++) {
await Promise.race([Promise.resolve(0), pendingPromise]);
}
// All tasks have completed, but pendingPromise retains the
// handlers attached by all 1000 races.
Promises bieten keine Mglichkeit, diese Handler abzumelden; sie bleiben angehngt, solange das Eingabe-Promise ausstehend und erreichbar ist. Brechen Sie, wo mglich, die zugrunde liegende Operation mithilfe eines AbortSignal ab, wenn das ausstehende Promise nicht mehr ntzlich ist.
Beachten Sie, dass JavaScript von Natur aus single-threaded ist. Daher wird zu einem bestimmten Zeitpunkt nur eine Aufgabe ausgefhrt, auch wenn die Steuerung zwischen verschiedenen Promises wechseln kann, wodurch die Ausfhrung der Promises gleichzeitig zu sein scheint. Parallele Ausfhrung in JavaScript kann nur ber Worker-Threads erreicht werden.
Promise()Erstellt ein neues Promise-Objekt. Der Konstruktor wird hauptschlich verwendet, um Funktionen zu kapseln, die noch keine Promises untersttzen.
Promise[Symbol.species]Gibt den Konstruktor zurck, der zum Erstellen von Rckgabewerten aus Promise-Methoden verwendet wird.
Promise.all()Akzeptiert ein Iterable von Promises als Eingabe und gibt ein einzelnes Promise zurck. Dieses zurckgegebene Promise wird erfllt, wenn alle Eingabe-Promises erfllt werden (auch wenn ein leeres Iterable bergeben wird), mit einem Array der Erfllungswerte. Es wird abgelehnt, wenn eines der Eingabe-Promises abgelehnt wird, mit diesem ersten Ablehnungsgrund.
Promise.allKeyed() Wie Promise.all(), auer dass es ein Objekt von Promises akzeptiert und ein Promise zurckgibt, das mit einem Objekt derselben Form erfllt wird. Dadurch knnen Sie Ergebnisse mit semantisch aussagekrftigen Schlsseln verknpfen.
Promise.allSettled()Akzeptiert ein Iterable von Promises als Eingabe und gibt ein einzelnes Promise zurck. Dieses zurckgegebene Promise wird erfllt, wenn alle Eingabe-Promises settled werden (auch wenn ein leeres Iterable bergeben wird), mit einem Array von Objekten, die das Ergebnis jedes Promise beschreiben.
Promise.allSettledKeyed() Wie Promise.allSettled(), auer dass es ein Objekt von Promises akzeptiert und ein Promise zurckgibt, das mit einem Objekt derselben Form erfllt wird. Dadurch knnen Sie Ergebnisse mit semantisch aussagekrftigen Schlsseln verknpfen.
Promise.any()Akzeptiert ein Iterable von Promises als Eingabe und gibt ein einzelnes Promise zurck. Dieses zurckgegebene Promise wird erfllt, wenn eines der Eingabe-Promises erfllt wird, mit diesem ersten Erfllungswert. Es wird abgelehnt, wenn alle Eingabe-Promises abgelehnt werden (auch wenn ein leeres Iterable bergeben wird), mit einem AggregateError, das ein Array von Ablehnungsgrnden enthlt.
Promise.race()Akzeptiert ein Iterable von Promises als Eingabe und gibt ein einzelnes Promise zurck. Dieses zurckgegebene Promise nimmt den eventuellen Zustand des ersten Promise an, das settled wird.
Promise.reject()Gibt ein neues Promise-Objekt zurck, das mit dem angegebenen Grund abgelehnt wird.
Promise.resolve()Gibt ein Promise-Objekt zurck, das mit dem angegebenen Wert aufgelst wird. Wenn der Wert ein thenable ist (d.h. eine then-Methode hat), wird das zurckgegebene Promise diesem thenable folgen und dessen eventuellen Zustand bernehmen; andernfalls wird das zurckgegebene Promise mit dem Wert erfllt.
Promise.try()Akzeptiert einen Callback beliebiger Art (gibt synchron oder asynchron zurck oder wirft) und lst dessen Ergebnis zu einem Promise auf.
Promise.withResolvers()Gibt ein Objekt zurck, das ein neues Promise-Objekt und zwei Funktionen zum Auflsen oder Ablehnen enthlt, entsprechend den zwei Parametern, die an den Executor des Konstruktors Promise() bergeben werden.
Diese Eigenschaften sind auf Promise.prototype definiert und werden von allen Promise-Instanzen gemeinsam genutzt.
Promise.prototype.constructorDie Konstruktorfunktion, die das Instanzobjekt erstellt hat. Fr Promise-Instanzen ist der Anfangswert der Konstruktor Promise.
Promise.prototype[Symbol.toStringTag]Der Anfangswert der Eigenschaft [Symbol.toStringTag] ist der String "Promise". Diese Eigenschaft wird in Object.prototype.toString() verwendet.
Promise.prototype.catch()Hngt einen rejection-handler-Callback an das Promise an und gibt ein neues Promise zurck, das zum Rckgabewert des Callbacks aufgelst wird, falls dieser aufgerufen wird, oder zum ursprnglichen Erfllungswert, falls das Promise stattdessen erfllt wird.
Promise.prototype.finally()Hngt einen Handler an das Promise an und gibt ein neues Promise zurck, das aufgelst wird, wenn das ursprngliche Promise aufgelst wird. Der Handler wird aufgerufen, wenn das Promise settled wird, unabhngig davon, ob es erfllt oder abgelehnt wurde.
Promise.prototype.then()Hngt fulfillment und rejection handlers an das Promise an und gibt ein neues Promise zurck, das zum Rckgabewert des aufgerufenen Handlers aufgelst wird oder zum ursprnglichen settled Wert, falls das Promise nicht behandelt wurde (d.h. wenn der relevante Handler onFulfilled oder onRejected keine Funktion ist).
In diesem Beispiel verwenden wir setTimeout(...), um asynchronen Code zu simulieren.
In der Praxis werden Sie wahrscheinlich etwas wie XHR oder eine HTML-API verwenden.
const myFirstPromise = new Promise((resolve, reject) => {
// We call resolve(...) when what we were doing asynchronously
// was successful, and reject(...) when it failed.
setTimeout(() => {
resolve("Success!"); // Yay! Everything went well!
}, 250);
});
myFirstPromise.then((successMessage) => {
// successMessage is whatever we passed in the resolve(...) function above.
// It doesn't have to be a string, but if it is only a succeed message, it probably will be.
console.log(`Yay! ${successMessage}`);
});
Dieses Beispiel zeigt verschiedene Techniken zur Verwendung von Promise-Funktionen und unterschiedliche Situationen, die auftreten knnen. Um dies zu verstehen, beginnen Sie damit, zum Ende des Codeblocks zu scrollen und die Promise-Kette zu untersuchen. Nach Bereitstellung eines initialen Promise kann eine Kette von Promises folgen. Die Kette besteht aus .then()-Aufrufen und hat typischerweise, aber nicht notwendigerweise, ein einzelnes .catch() am Ende, dem optional .finally() folgt. In diesem Beispiel wird die Promise-Kette durch ein selbst geschriebenes new Promise()-Konstrukt gestartet; in der Praxis beginnen Promise-Ketten jedoch hufiger mit einer API-Funktion (die von jemand anderem geschrieben wurde), die ein Promise zurckgibt.
Die Beispielfunktion tetheredGetNumber() zeigt, dass ein Promise-Generator reject() beim Einrichten eines asynchronen Aufrufs, innerhalb des Callbacks oder in beiden Fllen verwendet. Die Funktion promiseGetWord() veranschaulicht, wie eine API-Funktion ein Promise eigenstndig erzeugen und zurckgeben kann.
Beachten Sie, dass die Funktion troubleWithGetNumber() mit einem throw endet. Dies ist erforderlich, weil eine Promise-Kette alle .then()-Promises durchluft, selbst nach einem Fehler, und der Fehler ohne throw scheinbar behoben wre. Das ist umstndlich, und aus diesem Grund ist es blich, onRejected in der gesamten Kette von .then()-Promises wegzulassen und nur ein einzelnes onRejected im abschlieenden catch() zu verwenden.
Dieser Code kann unter Node.js ausgefhrt werden. Das Verstndnis wird verbessert, wenn Sie die Fehler tatschlich auftreten sehen. ndern Sie die threshold-Werte, um weitere Fehler zu erzwingen.
// To experiment with error handling, "threshold" values cause errors randomly
const THRESHOLD_A = 8; // can use zero 0 to guarantee error
function tetheredGetNumber(resolve, reject) {
setTimeout(() => {
const randomInt = Date.now();
const value = randomInt % 10;
if (value < THRESHOLD_A) {
resolve(value);
} else {
reject(new RangeError(`Too large: ${value}`));
}
}, 500);
}
function determineParity(value) {
const isOdd = value % 2 === 1;
return { value, isOdd };
}
function troubleWithGetNumber(reason) {
const err = new Error("Trouble getting number", { cause: reason });
console.error(err);
throw err;
}
function promiseGetWord(parityInfo) {
return new Promise((resolve, reject) => {
const { value, isOdd } = parityInfo;
if (value >= THRESHOLD_A - 1) {
reject(new RangeError(`Still too large: ${value}`));
} else {
parityInfo.wordEvenOdd = isOdd ? "odd" : "even";
resolve(parityInfo);
}
});
}
new Promise(tetheredGetNumber)
.then(determineParity, troubleWithGetNumber)
.then(promiseGetWord)
.then((info) => {
console.log(`Got: ${info.value}, ${info.wordEvenOdd}`);
return info;
})
.catch((reason) => {
if (reason.cause) {
console.error("Had previously handled error");
} else {
console.error(`Trouble with promiseGetWord(): ${reason}`);
}
})
.finally((info) => console.log("All done"));
Dieses kleine Beispiel zeigt den Mechanismus eines Promise. Die Methode testPromise() wird jedes Mal aufgerufen, wenn auf das <button> geklickt wird. Sie erstellt ein Promise, das mithilfe von setTimeout() nach zufllig 13 Sekunden mit der Promise-Anzahl (eine bei 1 beginnende Zahl) erfllt wird. Der Promise()-Konstruktor wird verwendet, um das Promise zu erstellen.
Die Erfllung des Promise wird ber einen fulfill callback protokolliert, der mit p1.then() festgelegt wurde. Einige Protokolle zeigen, wie der synchrone Teil der Methode vom asynchronen Abschluss des Promise entkoppelt ist.
Wenn Sie in kurzer Zeit mehrmals auf die Schaltflche klicken, werden Sie sogar sehen, wie die verschiedenen Promises nacheinander erfllt werden.
<button id="make-promise">Make a promise!</button>
<div id="log"></div>
"use strict";
let promiseCount = 0;
function testPromise() {
const thisPromiseCount = ++promiseCount;
const log = document.getElementById("log");
// begin
log.insertAdjacentHTML("beforeend", `${thisPromiseCount}) Started<br>`);
// We make a new promise: we promise a numeric count of this promise,
// starting from 1 (after waiting 3s)
const p1 = new Promise((resolve, reject) => {
// The executor function is called with the ability
// to resolve or reject the promise
log.insertAdjacentHTML(
"beforeend",
`${thisPromiseCount}) Promise constructor<br>`,
);
// This is only an example to create asynchronism
setTimeout(
() => {
// We fulfill the promise
resolve(thisPromiseCount);
},
Math.random() * 2000 + 1000,
);
});
// We define what to do when the promise is resolved with the then() call,
// and what to do when the promise is rejected with the catch() call
p1.then((val) => {
// Log the fulfillment value
log.insertAdjacentHTML("beforeend", `${val}) Promise fulfilled<br>`);
}).catch((reason) => {
// Log the rejection reason
console.log(`Handle rejected promise (${reason}) here.`);
});
// end
log.insertAdjacentHTML("beforeend", `${thisPromiseCount}) Promise made<br>`);
}
const btn = document.getElementById("make-promise");
btn.addEventListener("click", testPromise);
Ein weiteres Beispiel fr die Verwendung von Promise und XMLHttpRequest zum Laden eines Bildes ist unten dargestellt.
Jeder Schritt ist kommentiert und ermglicht es Ihnen, die Promise- und XHR-Architektur genau nachzuverfolgen.
<h1>Promise example</h1>
function imgLoad(url) {
// Create new promise with the Promise() constructor;
// This has as its argument a function with two parameters, resolve and reject
return new Promise((resolve, reject) => {
// XHR to load an image
const request = new XMLHttpRequest();
request.open("GET", url);
request.responseType = "blob";
// When the request loads, check whether it was successful
request.onload = () => {
if (request.status === 200) {
// If successful, resolve the promise by passing back the request response
resolve(request.response);
} else {
// If it fails, reject the promise with an error message
reject(
Error(
`Image didn't load successfully; error code: + ${request.statusText}`,
),
);
}
};
// Handle network errors
request.onerror = () => reject(new Error("There was a network error."));
// Send the request
request.send();
});
}
// Get a reference to the body element, and create a new image object
const body = document.querySelector("body");
const myImage = new Image();
const imgUrl =
"https://mdn.github.io/shared-assets/images/examples/round-balloon.png";
// Call the function with the URL we want to load, then chain the
// promise then() method with two callbacks
imgLoad(imgUrl).then(
(response) => {
// The first runs when the promise resolves, with the request.response
// specified within the resolve() method.
const imageURL = URL.createObjectURL(response);
myImage.src = imageURL;
body.appendChild(myImage);
},
(error) => {
// The second runs when the promise
// is rejected, and logs the Error specified with the reject() method.
console.log(error);
},
);
Ein Settings-Objekt ist eine Umgebung, die zustzliche Informationen bereitstellt, whrend JavaScript-Code ausgefhrt wird. Dazu gehren das Realm und die Modulzuordnung sowie HTML-spezifische Informationen wie die Origin. Das Incumbent-Settings-Objekt wird nachverfolgt, um sicherzustellen, dass der Browser wei, welches Objekt fr einen bestimmten Abschnitt von Benutzercode verwendet werden soll.
Um dies besser zu veranschaulichen, knnen wir genauer betrachten, warum das Realm ein Problem sein kann. Ein Realm kann grob als globales Objekt angesehen werden. Das Besondere an Realms ist, dass sie alle notwendigen Informationen zum Ausfhren von JavaScript-Code enthalten. Dazu gehren Objekte wie Array und Error. Jedes Settings-Objekt hat seine eigene Kopie davon, und diese werden nicht gemeinsam genutzt. Das kann im Zusammenhang mit Promises zu unerwartetem Verhalten fhren. Um dies zu umgehen, verfolgen wir etwas, das incumbent settings object genannt wird. Es reprsentiert Informationen, die spezifisch fr den Kontext des Benutzercodes sind, der fr einen bestimmten Funktionsaufruf verantwortlich ist.
Zur weiteren Veranschaulichung knnen wir betrachten, wie ein in ein Dokument eingebettetes <iframe> mit seinem Host kommuniziert. Da alle Web-APIs das Incumbent-Settings-Objekt kennen, funktioniert Folgendes in allen Browsern:
<!doctype html>
<iframe></iframe>
<!-- we have a realm here -->
<script>
// we have a realm here as well
const bound = frames[0].postMessage.bind(frames[0], "some data", "*");
// bound is a built-in function there is no user
// code on the stack, so which realm do we use?
setTimeout(bound);
// this still works, because we use the youngest
// realm (the incumbent) on the stack
</script>
Dasselbe Konzept gilt fr Promises. Wenn wir das obige Beispiel etwas ndern, erhalten wir Folgendes:
<!doctype html>
<iframe></iframe>
<!-- we have a realm here -->
<script>
// we have a realm here as well
const bound = frames[0].postMessage.bind(frames[0], "some data", "*");
// bound is a built in function there is no user
// code on the stack which realm do we use?
Promise.resolve(undefined).then(bound);
// this still works, because we use the youngest
// realm (the incumbent) on the stack
</script>
Wenn wir dies so ndern, dass das <iframe> im Dokument auf Post Messages lauscht, knnen wir die Auswirkung des Incumbent-Settings-Objekts beobachten:
<!-- y.html -->
<!doctype html>
<iframe src="x.html"></iframe>
<script>
const bound = frames[0].postMessage.bind(frames[0], "some data", "*");
Promise.resolve(undefined).then(bound);
</script>
<!-- x.html -->
<!doctype html>
<script>
window.addEventListener("message", (event) => {
document.querySelector("#text").textContent = "hello";
// this code will only run in browsers that track the incumbent settings object
console.log(event);
});
</script>
Im obigen Beispiel wird der innere Text des <iframe> nur aktualisiert, wenn das Incumbent-Settings-Objekt nachverfolgt wird. Denn ohne Nachverfolgung des Incumbent knnten wir am Ende die falsche Umgebung zum Senden der Nachricht verwenden.
Hinweis: Derzeit ist die Nachverfolgung des Incumbent-Realm in Firefox vollstndig implementiert und in Chrome und Safari teilweise implementiert.
| Spezifikation |
|---|
| ECMAScript 2027 LanguageSpecification # sec-promise-objects |
Promise in core-jsPromiseObject/FunctionDer Bauplan fr ein besseres Internet.
Teile dieses Inhalts sind 19982026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfgbar unter einer Creative-Commons-Lizenz.
| Web Proxy Viewer | New URL | Original Page |