Node.jsのpromiseを理解する


147

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

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

node-promiseライブラリを見つけましたが、取得できません。

誰かがすべての約束について、そしてなぜ私がそれを使うべきなのかを説明できますか?

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


この記事はそれをかなりよく説明しています。node.jsで使用可能な実装については、Futures
Sean Kinseyを

これが私が自分のpromiseクラスを作成するために使用した素晴らしいシリーズです:Let's Make a Framework:PromisesこれはjQuery Deferredに関するビデオです:blog.bigbinary.com/2011/09/03/jquery-deferred.html
Tom Winter

回答:


91

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

Promiseのすばらしい点は、Promiseを依存関係チェーンに結合できることです(Promise Cは、Promise A Promise Bが完了したときにのみ実行してください)。

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


10
@wengいいえ、そうではありません。
Ivo Wetzel 2010年

98

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

  1. node-promiseは私にはかなり死んでいるように見え(最後のコミットは約1年前でした)、ほとんどテストが含まれていません。
  2. 先物非常に私に肥大化したルックスをモジュールとひどく文書化されている(と私は命名規則がちょうど悪いと思います)
  3. 最善の方法は、アクティブで十分に文書化されているqフレームワークです。

9
このgithub.com/medikoo/deferredも確認してください。Qは最初の1つであり、その後登場した多くの実装にインスピレーションを与えていますが、残念ながら非常に遅く、「理論的」すぎる部分があり、一部ではうまく機能しません現実のシナリオ
Mariusz Nowak

私はRSVP.jsのクリエイターの一つで約束でこのビデオをチェックアウトしたい youtube.com/...
runspired

23
2014年の更新- ブルーバードは群を抜いて最速であり、今日最高のデバッグ能力を備えたものです。
Benjamin Gruenbaum 2014

19

約束は、いわば操作の「最終的な」結果を表す「もの」です。ここで注意すべき点は何かが発生したときの詳細を抽象化し、その発生後に発生するはずのことに集中できるようにすることです。これにより、クリーンでメンテナンス可能なコードが得られます。コールバック内のコールバック内にコールバックを置く代わりに、コードは次のようになります。

 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を返す必要があります。これは、実行する必要がある一連の非同期タスクがある場合に、promiseを連鎖させ、コールバックを使用した場合と同じように操作のシーケンスが保証されることを保証します。したがって、コールバック内のコールバック内にコールバックを渡す代わりに、チェーンされた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/


12

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

楽しい!

PS私はこの質問の他のいくつかの部分には答えませんでした。


これに対する私の唯一の謝罪は、高度な間違い#4の終わりにユーモアを読むことをあなたに強いることです。
Tony O'Hagan

実際、彼らがアンチパターンであると主張するチュートリアルのコードは、ループと条件の入れ子を必要とし、彼らが示唆するほど簡単にフラット化することはできません。
Bergi、

高度なミス#4は、はるかに多数の異なるアプローチを使用して解決することもできます。「。then()チェーンで以前のpromise結果にアクセスするにはどうすればよいですか?」を参照してください(彼らが提案する閉鎖パターンはあまり人気がないようです)。
Bergi、

このリンクのみの回答はコメントにした方がいいと思います。少なくともその記事の要点をここに回答してください。
Bergi、

7

Mike Taultyに、WinJS Promiseライブラリがどのように機能するかを説明する一連のビデオがあり、それぞれ10分未満です。

これらのビデオは非常に有益であり、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の参考資料にもかかわらず、Promise APIは多くの実装で広く類似しているため、これは一般的なビデオシリーズです。

お返事お願いしますは、Promise / A +テストスイートに合格する軽量のPromise実装です。WinJSインターフェースとスタイルが似ているので、私はAPIがとても好きです。

2014年4月の更新

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


1
+1。これは、私が理解し直感的に使用できる最初の例です。どういうわけか私の脳は、すべての解析できないdeferredsresolveしてdeferred.promise.thenとの事前に定義するpromiseActions人気のQライブラリのドキュメントに。Node.jsでこれほど簡単なことを知っている可能性はありますか?
Redsandro 2013年

1
@noel上記のリンクを共有していただきありがとうございます。これはPromiseの優れた入門シリーズであり、WinJSの詳細は全体的なアプローチ/トピックが普遍的であるため、無関係であることに同意します。
arcseldon 2014

いい例です。また、私はあなたの最初のリンクが死んでいたのを修正しました
stonedauwg

5

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

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


4

正確には何が約束ですか?

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

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

満たされた ::これは、約束が満たされたことを意味します。つまり、約束によって表される値を使用する準備ができていることを意味します。

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

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

  2. resolve :: resolveは、executor関数に渡されるパラメーターです。executorが正常に実行された場合、このresolveは、結果の受け渡しと呼ばれます。

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

したがって、promiseオブジェクトを作成するときは常に、Executor、Resolve、およびRejectを提供する必要があります。

リファレンス:: 約束


0

最近、node.jsでのプロミスについても調べています。これまでのところ、when.jsはその速度とリソースの使用のために進むべき道のようですが、q.jsのドキュメントは私に多くの理解を与えてくれました。したがって、主題を理解するには、when.jsを使用しますが、q.jsのドキュメントを使用します。

github のq.js readme から:

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


0

Promiseオブジェクトは、非同期操作の完了または失敗を表します。

したがって、promiseを実装するには、2つの部分が必要です。

1. 約束の作成:

promiseコンストラクターは、解決と拒否の2つのパラメーターを持つexecutorと呼ばれる関数を受け入れます。

function example(){
   return new Promise (function(resolve , reject){   //return promise object
      if(success){
         resolve('success');  //onFullfiled
      }else{
         reject('error');     //onRejected
      }
   })
}

2. 約束の処理:

Promiseオブジェクトには、Promiseオブジェクトを処理する3つのメソッドがあります。

1.Promise.prototype.catch(onRejected)

2.Promise.prototype.then(onFullfiled)

3.Promise.prototype.finally(onFullfiled、onRejected)

example.then((data) =>{
  //handles resolved data
  console.log(data); //prints success     
}).catch((err) => {
  //handles rejected error 
  console.log(err);  //prints error
})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.