web-dev-qa-db-ja.com

Node.jsのプロミスを理解する

私が理解したことから、非同期コードを呼び出す3つの方法があります。

  1. イベント、例request.on("event", callback);
  2. コールバック、例fs.open(path, flags, mode, callback);
  3. 約束

node-promise library が見つかりましたが、わかりません。

約束とは何か、なぜそれを使用する必要があるのか​​を誰かに説明してもらえますか?

また、Node.jsから削除されたのはなぜですか?

146
ajsie

Node.jsのPromisesはいくつかの作業を行うことを約束し、成功と失敗、タイムアウトの処理のために実行される個別のコールバックがありました。 node.jsのプロミスを考えるもう1つの方法は、それらが成功とエラーの2つのイベントのみを発行できるエミッターであるということです。

Promiseの素晴らしい点は、それらを依存関係チェーンに結合できることです(Promise AandPromise Bが完了した場合にのみPromise Cを実行します)。

コアのnode.jsからそれらを削除することで、コアの上に配置できるpromiseのさまざまな実装でモジュールを構築する可能性が生まれました。これらのいくつかは node-promise および futures です。

90
Paul Robinson

この質問には(私のように)まだ多くの意見があるので、私はそれを指摘したかった:

  1. node-promiseはかなり死んでいるように見え(最後のコミットは約1年前)、テストはほとんど含まれていません。
  2. futuresモジュールは非常に肥大化しているように見え、文書化も不十分です(そして、命名規則はただ悪いと思います)
  3. 最適な方法は q framework のようです。これはアクティブであり、十分に文書化されています。
98
enyo

約束は、いわば操作の「最終的な」結果を表す「もの」です。ここで注意すべき点は、when何かが起こった場合の詳細を抽象化し、起こるべきことに集中できることです何かが起こった後これにより、クリーンで保守可能なコードが作成され、コールバック内のコールバック内にコールバックを配置する代わりに、コードは次のようになります。

 var request = new Promise(function(resolve, reject) {
   //do an ajax call here. or a database request or whatever.
   //depending on its results, either call resolve(value) or reject(error)
   //where value is the thing which the operation's successful execution returns and
   //error is the thing which the operation's failure returns.
 });

 request.then(function successHandler(result) {
   //do something with the result
 }, function failureHandler(error) {
  //handle
 });

約束の仕様には、約束が

then

メソッドは、指定されたsuccessHandlerまたはfailureHandlerコールバックが終了したときに満たされる新しいpromiseを返す必要があります。これは、実行する必要がある非同期タスクのセットがある場合に、約束を連結でき、コールバックを使用したかのように操作の順序付けが保証されることを意味します。そのため、コールバック内のコールバック内にコールバックを渡す代わりに、連鎖プロミスのコードは次のようになります。

var doStuff = firstAsyncFunction(url) {
                return new Promise(function(resolve, reject) {
                       $.ajax({
                        url: url,
                        success: function(data) {
                            resolve(data);
                        },
                        error: function(err) {
                             reject(err); 
                        } 
                  });
               };
doStuff
  .then(secondAsyncFunction) //returns a promise
  .then(thirdAsyncFunction); //returns a promise

約束とそれがなぜとてもクールなのかをもっと知るには、Domenicのブログをチェックしてください: http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

19
Hrishi

PouchDB の作者によるPromisesの 新しいチュートリアル は、おそらく私がどこでも見た中で最高です。正しい使用パターンを示す古典的な新人の間違いや、他のチュートリアルでもまだ一般的に使用されているいくつかのアンチパターンを賢くカバーします!!

楽しい!

PSこの質問の他の部分は、他の部分で十分にカバーされているため、回答しませんでした。

12
Tony O'Hagan

Mike Taulty 一連のビデオがあります 、それぞれ10分未満の長さで、WinJS Promiseライブラリの動作を説明しています。

これらのビデオは非常に有益であり、Mikeはいくつかの適切なコード例を使用してPromise APIの力を示しています。

var twitterUrl = "http://search.Twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

例外の処理方法の扱いは特に優れています。

WinJsの参照にもかかわらず、これは一般的な興味のあるビデオシリーズです。PromiseAPIは多くの実装で広く類似しているためです。

RSVP は、Promise/A +テストスイートに合格する軽量のPromise実装です。 APIはスタイルがWinJSインターフェイスに似ているため、とても気に入っています。

2014年4月に更新

ちなみに、WinJSライブラリ 現在はオープンソース です。

7
Noel Abrahams

Promiseのもう1つの利点は、エラー処理と例外のスローとキャッチが、コールバックで処理しようとするよりもはるかに優れていることです。

bluebird ライブラリはpromiseを実装し、非常に長いスタックトレースを提供し、非常に高速で、捕捉できないエラーについて警告します。 http://bluebirdjs.com/docs/benchmarks.html によれば、他のpromiseライブラリよりも高速で、使用メモリも少なくなります。

5
llambda

Promiseとは何ですか?

Promiseは、非同期操作の結果を表す単なるオブジェクトです。約束は、次の3つの状態のいずれかになります。

pending::これは初期状態です。つまり、約束は履行も拒否もされません。

fulfilled::これは、promiseが満たされたことを意味し、promiseで表される値が使用できる状態であることを意味します。

rejected::これは操作が失敗したため、約束を果たすことができないことを意味します。州とは別に、私たちが本当に理解する必要がある約束に関連する3つの重要なエンティティがあります

  1. executor関数:: executor関数は、実行する必要があり、その結果がpromiseによって表される非同期操作を定義します。 promiseオブジェクトが初期化されるとすぐに実行が開始されます。

  2. resolve :: resolveはexecutor functionに渡されるパラメーターであり、executorが正常に実行される場合、この解決は結果を渡すと呼ばれます。

  3. reject :: rejectは、executor関数に渡される別のパラメーターであり、executor関数が失敗したときに使用されます。失敗の理由は拒否に渡すことができます。

そのため、promiseオブジェクトを作成するたびに、Executor、Resolve、およびRejectを提供する必要があります。

参照:: 約束

4
Rishabh.IO

最近node.jsの約束も検討しています。これまで、 when.js は速度とリソースの使用のために進むべき方法のように見えましたが、 q.js のドキュメントを読んで、よりよく理解できました。したがって、when.jsを使用しますが、主題を理解するにはq.jsのドキュメントを使用します。

Githubの q.js readmeから:

関数がブロックせずに値を返せない、または例外をスローできない場合、代わりにプロミスを返すことができます。 promiseは、関数が最終的に提供する可能性のある戻り値またはスローされた例外を表すオブジェクトです。 promiseは、遅延を克服するためにリモートオブジェクトのプロキシとしても使用できます。

0
Andrew Roberts