右の記事フィードバックのためのガイドを参照してコメントしてください。 ではPromiseを使っておつりを受け取る関数を作るとこうなります:, この関数はPromiseオブジェクトを返します。 JavaScript以外(例えばデータベース等)に仕事を任せてる間、その処理を待たないで次へ進めるという意味で非同期なのです。

What is going on with this article?

では、この関数を使って500円でりんごをひとつ買ってみましょう。, コールバックには、おつりやエラーをログに表示する無名関数を渡しています。 そしてaddEventListener()でloadイベントが発生した時点でlog(1)がキューに登録されます。 関数はキューに登録された順番にひとつずつ実行されていくので、ログはこうなります。, つまり、JavaScriptはXMLHttpRequestを使って外部と通信している間に、次の自分の仕事であるconsole.log(2)を進めているということです。 150円のリンゴを買ったときのおつりを計算して返すだけのシンプルな関数です:, 引数paymentに金額を渡すとchangeにおつりの金額、errorにnullが入ったオブジェクトを返します。 The JavaScript promises API will treat anything with a then() method as promise-like (or thenable in promise-speak sigh), so if you use a library that returns a Q promise, that's fine, it'll play nice with the new JavaScript promises. Promise オブジェクトは非同期処理の最終的な完了処理 (もしくは失敗) およびその結果の値を表現します。, プロミスの挙動と使用法について学ぶには、最初に Promise の使用をお読みください。, Promise インターフェイスは作成時点では分からなくてもよい値へのプロキシです。 Promise を用いることで、非同期アクションの成功や失敗に対するハンドラーを関連付けることができます。これにより、非同期メソッドは、最終的な値を返すのではなく、未来のある時点で値を持つ Promise を返すことで、同期メソッドと同じように値を返すことができるようになります。, 待機状態のプロミスは、何らかの値を持つ満足 (fulfilled) 状態、もしくは何らかの理由 (エラー) を持つ拒絶 (rejected) 状態のいずれかに変わります。そのどちらとなっても、then メソッドによって関連付けられたハンドラーが呼び出されます。 (対応するハンドラーが割り当てられたとき、既にプロミスが成功または失敗していても、そのハンドラーは呼ばれます。よって、非同期処理とその関連付けられたハンドラーとの競合は発生しません。), Promise.prototype.then() メソッドと Promise.prototype.catch() メソッドもまた Promise を返すので、これらをチェーン (連鎖) させることができます。, 混乱を避けるために: Scheme に代表されるいくつかの言語では、遅延評価や計算を延期する機構を持っており、これらも "Promise" と呼ばれます。 JavaScript における Promise は、すでに起きつつある処理を表します。そしてこの処理はコールバックを使うことでチェーンさせることができます。式を遅延評価する方法を探しているのであれば、引数なしのアロー関数を考えてください。 f = () => expression のように実現でき、遅延評価される式が作成され、 f() を呼ぶことでその式を評価できます。, 注: Promise は fulfilled か failed のどちらかになった場合は、 pending ではなく settled と呼ばれます。また解決 (resolved) という用語も目にされたことがあると思います。解決とは、Promise が解決または他の promise の状態にマッチするために" locked in "したことを意味します。States and fates では、 Promise の技術についてより詳細に述べられています。, promise.then(), promise.catch(), promise.finally() の各メソッドは、決定したプロミスにさらなるアクションを関連付けるために使用されます。これらのメソッドはまた、新しく生成されたプロミスオブジェクトを返します。例えば、このようになります。, 拒絶されたプロミスの処理が早すぎると、プロミスの連鎖のさらに下の方に影響を及ぼします。エラーはすぐに処理しなければならないので、選択の余地がないこともあります。 (結果を処理するためのテクニックについては、下記の例の throw -999 を参照してください。) 一方で、すぐに必要がない場合は、最後の .catch() 文までエラー処理をしない方がシンプルです。, これら2つの関数のシグネチャはシンプルで、任意の型の引数を1つだけ受け取ることができます。これらの関数を書くのはプログラマーです。これらの関数の終了条件は、チェーン内の次のプロミスの「解決」状態を決定します。 throw 以外の終了条件は "解決" の状態を生み出し、一方、 throw で終了すると "拒否" の状態を生み出します。, 返される nextValue は、別のプロミスオブジェクトにすることもでき、この場合はプロミスは動的にチェーンに挿入されます。, .then() が適切な関数欠いている場合、処理は単純にチェーンの次のリンクへと続きます。したがってチェーンは、すべての handleRejection を最後の .catch() まで、安全に省略することができます。 同様に、.catch() は、実際には handleFulfilled 用のスロットのないただの .then() です。, プロミスのチェーンはロシアの人形のように入れ子にすることができますが、スタックの最上位のように取り出します。チェーンの最初のプロミスは最も深いところに入れ子になり、最初に取り出されます。, nextValue がプロミスである場合、その効果は動的な置換です。 return によってプロミスが取り出されますが、 nextValue のプロミスはその場所に押し込まれます。上に示した入れ子では、"promise B" に関連付けられた .then() が "promise X" の nextValue を返すとします。 結果としての入れ子は以下のようになります。, プロミスは複数の入れ子に参加することができます。以下のコードでは、 promiseA が「確定」状態に移行すると、 .then() の両方のインスタンスが呼び出されます。, 既に「解決済み」のプロミスにアクションを割り当てることができます。その場合、アクションは (適切であれば) 最初の非同期の機会に実行されます。プロミスは非同期であることが保証されていることに注意してください。したがって、既に「解決済み」のプロミスに対するアクションは、スタックがクリアされ、クロックティックが経過した後にのみ実行されます。この効果は setTimeout(action,10) とよく似ています, この例では、プロミス機能を使用するための多様なテクニックと、発生する可能性のある多様な状況を示しています。これを理解するには、まずコードブロックの一番下までスクロールして、プロミスの連鎖を調べてください。最初のプロミスが提供されると、プロミスの連鎖が続きます。このチェーンは .then() の呼び出しで構成され、通常は (必ずしもそうとは限りませんが) 最後に単一の .catch() があり、オプションで .finally() が続きます。この例では、プロミスチェーンはカスタムで書かれた new Promise() コンストラクターによって開始されますが、実際には、プロミスチェーンは通常、プロミスを返す API 関数 (他の誰かが書いたもの) から開始されます。, 関数 tetheredGetNumber() の例では、非同期呼び出しを設定している間、またはコールバック内で、またはその両方で reject() を使用してプロミスを生成することを示しています。 関数 promiseGetWord() は、API 関数がどのように自己完結型の方法でプロミスを生成して返すかを示しています。, 関数 troubleWithGetNumber() は throw() で終わることに注意してください。これは、 ES6 のプロミスチェーンでは、エラーが発生した後で、 "throw()" がなく、エラーが "fixed" であるようにみえても、すべての .then() のプロミスを通過するため、強制的に行われています。これは面倒なので、 .then() プロミスのチェーン全体で rejectionFunc を省略して、最終的な catch() で単一の rejectionFunc を使用するのが一般的です。 別の方法としては、特別な値を投げるという方法があります (この場合は"-999" ですが、カスタムのエラー種別の方が適切です)。, このコードは NodeJS で実行できます。実際にエラーが発生しているのを見ることで理解度が高まります。より多くのエラーを強制的に発生させるには、 threshold の値を変更します。, 以下の例は Promise の仕組みを示したものです。 testPromise() メソッドは