Promise.prototype.then()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Die then()
Methode von Promise
Instanzen nimmt bis zu zwei Argumente entgegen: Callback-Funktionen für die erfüllten und abgelehnten Fälle des Promise
. Sie speichert die Callbacks innerhalb des Versprechens, auf dem sie aufgerufen wird, und gibt sofort ein weiteres Promise
Objekt zurück, was es Ihnen ermöglicht, Aufrufe an andere Promise-Methoden zu verketteln.
Probieren Sie es aus
const promise1 = new Promise((resolve, reject) => {
resolve("Success!");
});
promise1.then((value) => {
console.log(value);
// Expected output: "Success!"
});
Syntax
then(onFulfilled)
then(onFulfilled, onRejected)
Parameter
onFulfilled
-
Eine Funktion, die asynchron ausgeführt wird, wenn dieses Versprechen erfüllt wird. Ihr Rückgabewert wird zum Erfüllungswert des von
then()
zurückgegebenen Versprechens. Die Funktion wird mit folgenden Argumenten aufgerufen:value
-
Der Wert, mit dem das Versprechen erfüllt wurde.
Wenn es sich nicht um eine Funktion handelt, wird sie intern durch eine Identitätsfunktion (
(x) => x
) ersetzt, die den Erfüllungswert einfach weitergibt. onRejected
Optional-
Eine Funktion, die asynchron ausgeführt wird, wenn dieses Versprechen abgelehnt wird. Ihr Rückgabewert wird zum Erfüllungswert des von
then()
zurückgegebenen Versprechens. Die Funktion wird mit folgenden Argumenten aufgerufen:reason
-
Der Wert, mit dem das Versprechen abgelehnt wurde.
Wenn es sich nicht um eine Funktion handelt, wird sie intern durch eine Wurf-Funktion (
(x) => { throw x; }
) ersetzt, die den erhaltenen Ablehnungsgrund auslöst.
Rückgabewert
Gibt sofort ein neues Promise
zurück. Dieses neue Versprechen ist immer schwebend, wenn es zurückgegeben wird, unabhängig vom Status des aktuellen Versprechens.
Einer der onFulfilled
oder onRejected
Handler wird ausgeführt, um die Erfüllung oder Ablehnung des aktuellen Versprechens zu behandeln. Der Aufruf erfolgt immer asynchron, auch wenn das aktuelle Versprechen bereits erledigt ist. Das Verhalten des zurückgegebenen Versprechens (nennen wir es p
) hängt vom Ausführungsergebnis des Handlers ab und folgt einem spezifischen Satz von Regeln. Wenn die Handlerfunktion:
- einen Wert zurückgibt: wird
p
mit dem zurückgegebenen Wert als Wert erfüllt. - nichts zurückgibt: wird
p
mitundefined
als Wert erfüllt. - einen Fehler wirft: wird
p
mit dem geworfenen Fehler als Wert abgelehnt. - ein bereits erfülltes Versprechen zurückgibt: wird
p
mit dem Wert dieses Versprechens als Wert erfüllt. - ein bereits abgelehntes Versprechen zurückgibt: wird
p
mit dem Wert dieses Versprechens als Wert abgelehnt. - ein weiteres schwebendes Versprechen zurückgibt: ist
p
schwebend und wird sofort nach Erfüllung/Ablehnung dieses Versprechens mit dessen Wert als Wert erfüllt/abgelehnt.
Beschreibung
Die then()
Methode plant Callback-Funktionen für den eventuellen Abschluss eines Versprechens — entweder Erfüllung oder Ablehnung. Sie ist die primitive Methode von Versprechungen: das mit thenable arbeitende Protokoll erwartet von allen versprechensartigen Objekten, dass sie eine then()
Methode bereitstellen, und die catch()
und finally()
Methoden funktionieren beide durch den Aufruf der then()
Methode des Objekts.
Für weitere Informationen über den onRejected
Handler siehe die catch()
Referenz.
then()
gibt ein neues Versprechenobjekt zurück, modifiziert jedoch das Versprechenobjekt, auf dem es aufgerufen wird, indem es die Handler an eine interne Liste anhängt. Daher wird der Handler vom ursprünglichen Versprechen gehalten und seine Lebensdauer ist mindestens so lang wie die des ursprünglichen Versprechens. Zum Beispiel wird folgendes Beispiel schließlich den Speicher überbeanspruchen, auch wenn das zurückgegebene Versprechen nicht gehalten wird:
const pendingPromise = new Promise(() => {});
while (true) {
pendingPromise.then(doSomething);
}
Wenn Sie die then()
Methode zweimal auf demselben Versprechenobjekt aufrufen (anstatt zu verketten), hat dieses Versprechenobjekt zwei Paare von Abschluss-Handlern. Alle an dasselbe Versprechenobjekt angehängten Handler werden immer in der Reihenfolge aufgerufen, in der sie hinzugefügt wurden. Außerdem starten die beiden durch jeden Aufruf von then()
zurückgegebenen Versprechen separate Ketten und warten nicht auf die Erfüllung des jeweils anderen.
Thenable Objekte, die entlang der then()
Kette auftauchen, werden immer aufgelöst — der onFulfilled
Handler erhält niemals ein thenable Objekt, und any thenable, das von einem der beiden Handler zurückgegeben wird, wird immer aufgelöst, bevor es an den nächsten Handler weitergegeben wird. Dies liegt daran, dass beim Erstellen des neuen Versprechens die vom executor
übergebenen resolve
und reject
Funktionen gespeichert werden, und wenn das aktuelle Versprechen abgeschlossen wird, die jeweilige Funktion mit dem Erfüllungswert oder Ablehnungsgrund aufgerufen wird. Die Auflösung erfolgt durch die resolve
Funktion, die vom Promise()
Konstruktor übergeben wird.
then()
unterstützt Subclassing, was bedeutet, dass sie auf Instanzen von Unterklassen von Promise
aufgerufen werden kann, und das Ergebnis wird ein Versprechen des Unterklassentyps sein. Sie können den Typ des Rückgabewerts durch die [Symbol.species]
Eigenschaft anpassen.
Beispiele
Verwendung der then() Methode
const p1 = new Promise((resolve, reject) => {
resolve("Success!");
// or
// reject(new Error("Error!"));
});
p1.then(
(value) => {
console.log(value); // Success!
},
(reason) => {
console.error(reason); // Error!
},
);
Eine Nicht-Funktion als einen der Parameter
Promise.resolve(1).then(2).then(console.log); // 1
Promise.reject(new Error("failed")).then(2, 2).then(console.log, console.log); // Error: failed
Verkettung
Die then
Methode gibt ein neues Promise
zurück, das Verkettung von Methoden ermöglicht.
Wenn die als Handler an then
übergebene Funktion ein Promise
zurückgibt, wird ein gleichwertiges Promise
dem nachfolgenden then
in der Methodenkette ausgesetzt. Der folgende Ausschnitt simuliert asynchronen Code mit der setTimeout
Funktion.
Promise.resolve("foo")
// 1. Receive "foo", concatenate "bar" to it, and resolve that to the next then
.then(
(string) =>
new Promise((resolve, reject) => {
setTimeout(() => {
string += "bar";
resolve(string);
}, 1);
}),
)
// 2. receive "foobar", register a callback function to work on that string
// and print it to the console, but not before returning the unworked on
// string to the next then
.then((string) => {
setTimeout(() => {
string += "baz";
console.log(string); // foobarbaz
}, 1);
return string;
})
// 3. print helpful messages about how the code in this section will be run
// before the string is actually processed by the mocked asynchronous code in the
// previous then block.
.then((string) => {
console.log(
"Last Then: oops... didn't bother to instantiate and return a promise in the prior then so the sequence may be a bit surprising",
);
// Note that `string` will not have the 'baz' bit of it at this point. This
// is because we mocked that to happen asynchronously with a setTimeout function
console.log(string); // foobar
});
// Logs, in order:
// Last Then: oops... didn't bother to instantiate and return a promise in the prior then so the sequence may be a bit surprising
// foobar
// foobarbaz
Der von then()
zurückgegebene Wert wird auf die gleiche Weise aufgelöst wie Promise.resolve()
. Das bedeutet, dass thenable Objekte unterstützt werden und wenn der Rückgabewert kein Versprechen ist, wird er implizit in ein Promise
eingeschlossen und dann aufgelöst.
const p2 = new Promise((resolve, reject) => {
resolve(1);
});
p2.then((value) => {
console.log(value); // 1
return value + 1;
}).then((value) => {
console.log(value, "- A synchronous value works"); // 2 - A synchronous value works
});
p2.then((value) => {
console.log(value); // 1
});
Ein then
Aufruf gibt ein Versprechen zurück, das schließlich ablehnt, wenn die Funktion einen Fehler wirft oder ein abgelehntes Versprechen zurückgibt.
Promise.resolve()
.then(() => {
// Makes .then() return a rejected promise
throw new Error("Oh no!");
})
.then(
() => {
console.log("Not called.");
},
(error) => {
console.error(`onRejected function called: ${error.message}`);
},
);
In der Praxis ist es oft wünschenswert, abgelehnte Versprechen mit catch()
abzufangen, anstatt die Zwei-Fall-Syntax von then()
zu verwenden, wie unten gezeigt.
Promise.resolve()
.then(() => {
// Makes .then() return a rejected promise
throw new Error("Oh no!");
})
.catch((error) => {
console.error(`onRejected function called: ${error.message}`);
})
.then(() => {
console.log("I am always called even if the prior then's promise rejects");
});
In allen anderen Fällen wird das zurückgegebene Versprechen schließlich erfüllt. Im folgenden Beispiel gibt das erste then()
42
umschlossen von einem erfüllten Versprechen zurück, obwohl das vorherige Versprechen in der Kette abgelehnt wurde.
Promise.reject(new Error("Oh no!"))
.then(
() => 99,
() => 42,
) // onRejected returns 42 which is wrapped in a fulfilled Promise
.then((solution) => console.log(`Resolved with ${solution}`)); // Fulfilled with 42
Wenn onFulfilled
ein Versprechen zurückgibt, wird der Rückgabewert von then
je nach dem endgültigen Zustand dieses Versprechens erfüllt/abgelehnt.
function resolveLater(resolve, reject) {
setTimeout(() => {
resolve(10);
}, 1000);
}
function rejectLater(resolve, reject) {
setTimeout(() => {
reject(new Error("Error"));
}, 1000);
}
const p1 = Promise.resolve("foo");
// Return promise here, that will be resolved to 10 after 1 second
const p2 = p1.then(() => new Promise(resolveLater));
p2.then(
(v) => {
console.log("resolved", v); // "resolved", 10
},
(e) => {
// not called
console.error("rejected", e);
},
);
// Return promise here, that will be rejected with 'Error' after 1 second
const p3 = p1.then(() => new Promise(rejectLater));
p3.then(
(v) => {
// not called
console.log("resolved", v);
},
(e) => {
console.error("rejected", e); // "rejected", 'Error'
},
);
Sie können Verkettung verwenden, um eine Funktion mit einer auf Versprechen basierenden API auf einer anderen solchen Funktion zu implementieren.
function fetchCurrentData() {
// The fetch() API returns a Promise. This function
// exposes a similar API, except the fulfillment
// value of this function's Promise has had more
// work done on it.
return fetch("current-data.json").then((response) => {
if (response.headers.get("content-type") !== "application/json") {
throw new TypeError();
}
const j = response.json();
// maybe do something with j
// fulfillment value given to user of
// fetchCurrentData().then()
return j;
});
}
Asynchronität von then()
Das Folgende ist ein Beispiel, um die Asynchronität der then
Methode zu demonstrieren.
// Using a resolved promise 'resolvedProm' for example,
// the function call 'resolvedProm.then(...)' returns a new promise immediately,
// but its handler '(value) => {...}' will get called asynchronously as demonstrated by the console.logs.
// the new promise is assigned to 'thenProm',
// and thenProm will be resolved with the value returned by handler
const resolvedProm = Promise.resolve(33);
console.log(resolvedProm);
const thenProm = resolvedProm.then((value) => {
console.log(
`this gets called after the end of the main stack. the value received is: ${value}, the value returned is: ${
value + 1
}`,
);
return value + 1;
});
console.log(thenProm);
// Using setTimeout, we can postpone the execution of a function to the moment the stack is empty
setTimeout(() => {
console.log(thenProm);
});
// Logs, in order:
// Promise {[[PromiseStatus]]: "resolved", [[PromiseResult]]: 33}
// Promise {[[PromiseStatus]]: "pending", [[PromiseResult]]: undefined}
// "this gets called after the end of the main stack. the value received is: 33, the value returned is: 34"
// Promise {[[PromiseStatus]]: "resolved", [[PromiseResult]]: 34}
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification # sec-promise.prototype.then |