Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web/JavaScript/Reference/Global_Objects/Promise/finally 他2件を更新 #23957

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
title: Promise.prototype.finally()
slug: Web/JavaScript/Reference/Global_Objects/Promise/finally
l10n:
sourceCommit: 2eb202adbe3d83292500ed46344d63fbbae410b5
sourceCommit: 8421c0cd94fa5aa237c833ac6d24885edbc7d721
---

{{JSRef}}

**`finally()`** は {{jsxref("Promise")}} のメソッドで、プロミスが決定したとき(履行されたか拒否されたかのどちらか)に呼び出される関数を準備します。直ちに同等の {{jsxref("Promise")}} オブジェクトを返すため、プロミスの他のメソッドを[連鎖](/ja/docs/Web/JavaScript/Guide/Using_promises#連鎖)呼び出しすることができます。
**`finally()`** は {{jsxref("Promise")}} インスタンスのメソッドで、プロミスが決定したとき(履行されたか拒否されたかのどちらか)に呼び出される関数を準備します。直ちに他の {{jsxref("Promise")}} オブジェクトを返すため、プロミスの他のメソッドを[連鎖](/ja/docs/Web/JavaScript/Guide/Using_promises#連鎖)呼び出しすることができます。

これによって、プロミスの {{jsxref("Promise/then", "then()")}} ハンドラーと {{jsxref("Promise/catch", "catch()")}} ハンドラーでコードが重複することを避けることができます。

Expand All @@ -16,21 +16,17 @@ l10n:
## 構文

```js-nolint
finally(onFinally)

finally(() => {
// プロミスの決定(履行または拒否)後に実行されるコード
})
promiseInstance.finally(onFinally)
```

### 引数

- `onFinally`
- : `Promise` が決定したら呼び出される関数 ({{jsxref("Function")}}) です。このハンドラーは引数を取りません
- : このプロミスが決定したときに非同期で実行する関数です。返値が拒否されたプロミスでない限り、その返値は無視されます。関数は引数なしで呼び出されます

### 返値

同等の {{jsxref("Promise")}} を返します。ハンドラーがエラーを発生したり、拒否されたプロミスを返したりした場合、代わりに `finally()` が返すプロミスがその値で拒否されます。そうでなければ、ハンドラーの返す値は元のプロミスの状態に影響しません
同等の {{jsxref("Promise")}} を返します。この新しいプロミスは、現在のプロミスの状態に関わらず、常に返されるまで待機します。 `onFinally` でエラーが発生したり、拒否されたプロミスが返された場合、新しいプロミスは同じ値で拒否されます。それ以外の場合、新しいプロミスは現在のプロミスと同じ状態で決定されます

## 解説

Expand All @@ -40,7 +36,7 @@ finally(() => {

- 関数をインラインで作成する場合、関数を 2 度宣言するか、変数を作成するかのどちらかで、一度に渡すことができます。
- `onFinally` コールバックは一切引数を受け取りません。この用途では、拒否された理由や履行された値などを提供する必要がなく、それらを気にしないときに適しています。
- `finally()` の呼び出しは通常透過的で、元のプロミスの最終的な状態を変更することはありません。ですから例えば、
- 通常、`finally()` を呼び出すと、元のプロミスの最終的な状態を反映するようになります。ですから例えば、
- `Promise.resolve(2).then(() => 77, () => {})` が最終的に `77` の値で履行されるプロミスを返すのとは異なり、`Promise.resolve(2).finally(() => 77)` は最終的に `2` の値で履行されるプロミスを返します。
- 同様に、`Promise.reject(3).then(() => {}, () => 88)` が最終的に `88` の値で履行されるプロミスを返すのとは異なり、`Promise.reject(3).finally(() => 88)` は最終的に `3` の値で拒否されるプロミスを返します。

Expand All @@ -61,7 +57,7 @@ promise.then(
);
```

`finally()` は `then()` を呼び出すので、サブクラス化に対応しています。さらに、上記の {{jsxref("Promise.resolve()")}} の呼び出しに注目してください。実際には、 `onFinally()` の返値は `Promise.resolve()` と同じアルゴリズムで解決されますが、解決されたプロミスを構築するために使用される実際のコンストラクターはサブクラスとなります。 `finally()` はこのコンストラクターを [`promise.constructor[@@species]`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/@@species) で取得します。
`finally()` は `then()` を呼び出すので、サブクラス化に対応しています。さらに、上記の {{jsxref("Promise.resolve()")}} の呼び出しに注目してください。実際には、 `onFinally()` の返値は `Promise.resolve()` と同じアルゴリズムで解決されますが、解決されたプロミスを構築するために使用される実際のコンストラクターはサブクラスとなります。 `finally()` はこのコンストラクターを [`promise.constructor[Symbol.species]`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/Symbol.species) で取得します。

## 例

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
title: Promise.resolve()
slug: Web/JavaScript/Reference/Global_Objects/Promise/resolve
l10n:
sourceCommit: 3fe5c1d405128b70e38347931153fd2ce10b3545
sourceCommit: 8421c0cd94fa5aa237c833ac6d24885edbc7d721
---

{{JSRef}}

**`Promise.resolve()`** は静的メソッドで、 {{jsxref("Promise")}} を与えられた値で「解決」させます。値がプロミスの場合は、そのプロミスが返されます。その値が [Thenable](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenables) であれば、`Promise.resolve()` は `then()` メソッドを、準備した 2 つのコールバックと共に呼び出します。それ以外の場合は、その値で履行するプロミスが返されます。
**`Promise.resolve()`** は静的メソッドで、 {{jsxref("Promise")}} を与えられた値で「解決」させます。値がプロミスの場合は、そのプロミスが返されます。その値が [Thenable](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenable) であれば、`Promise.resolve()` は `then()` メソッドを、準備した 2 つのコールバックと共に呼び出します。それ以外の場合は、その値で履行するプロミスが返されます。

この関数は複数階層のプロミス風オブジェクト (例えば、何かで解決するプロミスで解決するプロミス) を単一の階層に平坦化します。

Expand All @@ -32,14 +32,16 @@ Promise.resolve(value)

`Promise.resolve()` はプロミスを _解決_ します。これはプロミスを履行したり拒否したりすることとは異なります。用語の定義については、[プロミスの説明](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#description)を参照してください。簡単に言うと、 `Promise.resolve()` は、最終的な状態が他のプロミス、 Thenable オブジェクト、または他の値に依存しているプロミスを返します。

`Promise.resolve()` は汎用で、サブクラス化を対応しています。つまり、`Promise` のサブクラスで呼び出すことができ、その結果はサブクラス型のプロミスになります。これを行うには、サブクラスのコンストラクターは [`Promise()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) コンストラクターと同じ定義で実装する必要があります。引数として `resolve` と `reject` コールバックで呼び出すことができる単一の `executor` 関数を受け入れることができます。
> **メモ:** `value` 式の評価で同期的にエラーが発生する可能性がある場合、このエラーは捕捉されず、`Promise.resolve()` によって拒否されたプロミスにラップされます。この用途には {{jsxref("Promise/try", "Promise.try(() => value)")}} を使用することを検討してください。

`Promise.resolve()` は汎用で、サブクラス化に対応しています。つまり、`Promise` のサブクラスで呼び出すことができ、その結果はサブクラス型のプロミスになります。これを行うには、サブクラスのコンストラクターは [`Promise()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise) コンストラクターと同じ定義で実装する必要があります。引数として `resolve` と `reject` コールバックで呼び出すことができる単一の `executor` 関数を受け入れることができます。

`Promise.resolve()` は、ネイティブの `Promise` のインスタンスを特別扱いしています。 `value` が `Promise` またはそのサブクラスに属し、 `value.constructor === Promise` の場合、新しい `Promise` インスタンスを作成せずに、`Promise.resolve()` で直接 `value` を返すことができます。そうでない場合、`Promise.resolve()` は基本的に `new Promise((resolve) => resolve(value))` の一括指定となります。

解決ロジックの大部分は,実際には `Promise()` コンストラクターに渡される[リゾルバー関数](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise#resolver_function)で実装されます。概要をまとめると、次のようになります。
解決ロジックの大部分は,実際には `Promise()` コンストラクターに渡される [`resolve` 関数](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise#resolve_関数)で実装されます。概要をまとめると、次のようになります。

- [Thenable](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenables) でない値が渡された場合,返されたプロミスはその値ですでに履行されたものとなります。
Thenable が渡された場合、`then` メソッドを呼び出され、引数としてリゾルバー関数のペアを渡すことで、返されるプロミスはその Thenable の状態を採用することになります。(しかし、ネイティブのプロミスはラッパーを作成せずに直接 `Promise.resolve()` を通すので、ネイティブのプロミスでは `then` メソッドは呼ばれません)。リゾルバー関数が別の Thenable オブジェクトを受け取ると、それは再び解決されるので、最終的なプロミスの履行値は決して Thenable になることはないでしょう。
- [Thenable](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise#thenable) でない値が渡された場合,返されたプロミスはその値ですでに履行されたものとなります。
Thenable が渡された場合、`then` メソッドを呼び出され、引数として解決関数のペアを渡すことで、返されるプロミスはその Thenable の状態を採用することになります。(しかし、ネイティブのプロミスはラッパーを作成せずに直接 `Promise.resolve()` を通すので、ネイティブのプロミスでは `then` メソッドは呼ばれません)。`resolve` 関数が別の Thenable オブジェクトを受け取ると、それは再び解決されるので、最終的なプロミスの履行値は決して Thenable になることはないでしょう。

## 例

Expand Down Expand Up @@ -104,16 +106,13 @@ p1.then(
},
);

// Thenable throws before callback
// Thenable throws
// Promise rejects
const thenable = {
then(onFulfilled) {
const p2 = Promise.resolve({
then() {
throw new TypeError("Throwing");
onFulfilled("Resolving");
},
};

const p2 = Promise.resolve(thenable);
});
p2.then(
(v) => {
// 呼び出されない
Expand All @@ -130,9 +129,7 @@ const thenable = {
onFulfilled("Resolving");
throw new TypeError("Throwing");
},
};

const p3 = Promise.resolve(thenable);
});
p3.then(
(v) => {
console.log(v); // "Resolving"
Expand Down Expand Up @@ -177,7 +174,7 @@ Promise.resolve(thenable); // 無限の再帰を引き起こす

### Promise 以外のコンストラクターに対する resolve() の呼び出し

`Promise.resolve()` は汎用的なメソッドです。これは `Promise()` コンストラクタと同じ定義を実装した任意のコンストラクターで呼び出すことができます。例えば、`resolve` として `console.log` を渡すコンストラクターで呼び出すことができます。
`Promise.resolve()` は汎用的なメソッドです。これは `Promise()` コンストラクターと同じ定義を実装した任意のコンストラクターで呼び出すことができます。例えば、`resolve` として `console.log` を渡すコンストラクターで呼び出すことができます。

```js
class NotPromise {
Expand All @@ -194,7 +191,7 @@ class NotPromise {
Promise.resolve.call(NotPromise, "foo"); // Logs "Resolved foo"
```

入れ子になった Thenable を平坦化する機能は `Promise()` コンストラクターのリゾルバー関数で実装されています。そのため、他のコンストラクターで呼び出すと、そのコンストラクターがリゾルバーをどのように実装しているかによって入れ子の Thenable が平坦化されない場合があります。
入れ子になった Thenable を平坦化する機能は `Promise()` コンストラクターの `resolve` 関数で実装されています。そのため、他のコンストラクターで呼び出すと、そのコンストラクターが `resolve` 関数をどのように実装しているかによって入れ子の Thenable が平坦化されない場合があります。

```js
const thenable = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
---
title: get Promise[@@species]
title: Promise[Symbol.species]
slug: Web/JavaScript/Reference/Global_Objects/Promise/Symbol.species
original_slug: Web/JavaScript/Reference/Global_Objects/Promise/@@species
l10n:
sourceCommit: 0f248adcab759bdad247a5dbfb7da12dc32bce59
sourceCommit: 8421c0cd94fa5aa237c833ac6d24885edbc7d721
---

{{JSRef}}

**`Promise[@@species]`** アクセサープロパティは、プロミスのメソッドからの返値を構築するのに使用されるコンストラクターを返します。
**`Promise[Symbol.species]`** アクセサープロパティは、プロミスのメソッドからの返値を構築するのに使用されるコンストラクターを返します。

> **警告:** `@@species` が存在すると、任意のコードの実行が可能になり、セキュリティ上の脆弱性を生み出す可能性があります。また、特定の最適化も非常に難しくなります。エンジンの実装者は[この機能を削除するかどうか調査](https://github.com/tc39/proposal-rm-builtin-subclassing)しています。可能であれば、この機能に頼ることは避けてください。
> **警告:** `Symbol.species` が存在すると、任意のコードの実行が可能になり、セキュリティ上の脆弱性を生み出す可能性があります。また、特定の最適化も非常に難しくなります。エンジンの実装者は[この機能を削除するかどうか調査](https://github.com/tc39/proposal-rm-builtin-subclassing)しています。可能であれば、この機能に頼ることは避けてください。

## 構文

```js
Promise[Symbol.species];
```js-nolint
Promise[Symbol.species]
```

### 返値

`get @@species` が呼び出されたコンストラクター (`this`) の値です。この返値は、新しいプロミスを作成するプロミス連鎖メソッドから返値を作成するために使用されます。
`get [Symbol.species]` が呼び出されたコンストラクター (`this`) の値です。この返値は、新しいプロミスを作成するプロミス連鎖メソッドから返値を作成するために使用されます。

## 解説

`@@species` アクセサープロパティは `Promise` オブジェクトの既定のコンストラクターを返します。サブクラスのコンストラクターはこれを上書きしてコンストラクターの割り当てを変更することができます。既定の実装では、基本的に次のようになります。
`[Symbol.species]` アクセサープロパティは `Promise` オブジェクトの既定のコンストラクターを返します。サブクラスのコンストラクターはこれを上書きしてコンストラクターの割り当てを変更することができます。既定の実装では、基本的に次のようになります。

```js
// 解説のため架空の基礎実装
Expand All @@ -35,14 +34,14 @@ class Promise {
}
```

この多相的な実装のため、派生したサブクラスの `@@species` も既定ではコンストラクター自身を返すことになります。
この多相的な実装のため、派生したサブクラスの `[Symbol.species]` も既定ではコンストラクター自身を返すことになります。

```js
class SubPromise extends Promise {}
SubPromise[Symbol.species] === Promise; // true
SubPromise[Symbol.species] === SubPromise; // true
```

プロミス連鎖メソッドである [`then()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then)、[`catch()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch)、[`finally()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally) は、新しいプロミスオブジェクトを返します。これらは `this.constructor[@@species]` を介して新しいプロミスを構築するためのコンストラクターを取得します。 `this.constructor` が `undefined` の場合、または `this.constructor[@@species]` が `undefined` または `null` の場合、既定の {{jsxref("Promise/Promise", "Promise()")}} コンストラクターが使用されます。それ以外の場合は、 `this.constructor[@@species]` から返されるコンストラクターが使用され、新しいプロミスオブジェクトが構築されます。
プロミス連鎖メソッドである [`then()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/then)、[`catch()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch)、[`finally()`](/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally) は、新しいプロミスオブジェクトを返します。これらは `this.constructor[Symbol.species]` を介して新しいプロミスを構築するためのコンストラクターを取得します。 `this.constructor` が `undefined` の場合、または `this.constructor[Symbol.species]` が `undefined` または `null` の場合、既定の {{jsxref("Promise/Promise", "Promise()")}} コンストラクターが使用されます。それ以外の場合は、 `this.constructor[Symbol.species]` から返されるコンストラクターが使用され、新しいプロミスオブジェクトが構築されます。

## 例

Expand Down Expand Up @@ -77,7 +76,7 @@ class MyPromise extends Promise {
console.log(MyPromise.resolve(1).then(() => {}).someValue); // 1
```

`@@species` を上書きすることで、プロミスのメソッドは基底の `Promise` 型を返すことになります。
`[Symbol.species]` を上書きすることで、プロミスのメソッドは基底の `Promise` 型を返すことになります。

```js
class MyPromise extends Promise {
Expand Down