JavaScriptの約束


約束は、我々が非同期操作を実行するのを許します.エーPromise あなたがそうするならば、代理人、代入者、我々が約束を宣言するとき、必ずしも知られていない値です.すぐに最終的な値を持っている代わりに、我々は最終的な価値があるという約束を持ちます.
データベースからデータを保存したり、データを取得したり、APIからデータを取得したりするときに便利です.

どのように約束を作成する
約束を作成するには、単にオブジェクトの新しいインスタンスを作成し、resolve and reject パラメータ.
const promise = new Promise((resolve, reject) => /* do things */)
resolve 非同期アクションが正常に終了した場合に呼び出されます.reject 約束は3つの異なる状態を持つことができます.
  • pending は初期状態です.
  • fulfilled 操作が正常に完了したか、完了したことを意味します
  • rejected 操作が失敗したことを意味します
  • それで、約束が最初につくられるとき、その状態はそうですpending . そして、一旦非同期操作が起こったならば、それがうまく解決されるならば、その状態はなるでしょうfulfilled 関数をコールしますresolve . そうでなければ、rejected 関数をコールするreject .
    それで、約束の簡単な例は次のようになります.
    const promise = new Promise((resolve, reject) => {
       console.log('Asynchronous operation started')
       setTimeout(() => Math.random() > 0.15
          ? resolve('Success!')
          : reject('Oops, something went wrong!')
       , Math.random() * 700 + 800)
    })
    
    我々がここで得る最初のことは、我々のコンソールで我々が操作が始まったということを知らせているメッセージです.その後、0.8から1.5秒後、約束は解決(時間の85 %)と成功メッセージを返すか失敗する(〜15 %のチャンス)と失敗メッセージを返します.
    then and catch または約束が解決するときに何が起こる
    ほとんどの場合、非同期操作が解決した後に、返されたデータで何かをしたいと思います.たとえば、データベースから情報を取得する場合、実際にその情報を使用することができます.それが方法ですthen and catch 都合がいい.
    then方法then つのオプションパラメータを受け取ります.onFulfilled and onRejected . 約束があるならば、最初のものは呼ばれますfulfilled そして2番目のものがrejected . 両方の関数は1つの引数を得ます.
    我々の前の約束に基づいて、それは以下のように見えるかもしれません:
    promise.then(data => {
       writeMsg(data) // Writes 'Success!'
       launchFireworks() // Launches fireworks
    }, rejection => {
       writeMsg(rejection) // Writes 'Oops, something went wrong!'
       playDefeatMusic() // Plays sad, defeat music
    })
    
    多くの場合、しかし、あなたはonFulfilled パラメータを指定し、catch メソッド.それで、我々はちょうどこれを書くことができました:
    promise.then(data => {
       writeMsg(data)
       launchFireworks()
    })
    
    あなたが1つの機能をthen , あなたはその名前とthen 関数の引数として、それを呼び出し、その約束の結果を渡すことを気にします.
    //Both these thens do the same
    promise.then(data => doStuff(data))
    promise.then(doStuff)
    
    catch方法catch パラメータを受け入れるonRejected , 約束が拒絶されるならば、どちらが呼ばれます.それ以外は、正確に動作しますthen .
    promise
       .then(data => {
          writeMsg(data)
          launchFireworks()
       })
       .catch(error => {
          writeMsg(error)
          playDefeatMusic()
       })
    
    そしてthen , Shortandを呼び出すときに使用できます.
    promise
       .then(doStuff)
       .catch(logError)
    

    チェーンthen and catch何でも返しますthen and catch また、約束に包まれます.それで、彼らが本当に非同期のものをしていないとしても、彼らを連鎖させることが可能です.
    promise
       .then(transformData)
       .then(doMoreAsyncStuff)
       .then(transformData)
       .catch(dealWithError)
    
    しかし、多分、我々は実際の例を見ました.我々が運動セッションについてデータを保存するためにMongoDBを使っていると仮定しましょう.いくつかの時点で、我々は、データを取得したい.このようなことができました.
    const mongoDB = require('mongodb')
    
    mongoDB.MongoClient.connect(URI)
       .then(client => client.db('exercise'))
       .then(db => db.collection('workouts').find(query))
       .then(data => data.toArray())
       .then(console.log)
       .catch(console.warn)
    
    これは既に自分自身で約束を返します.データベースを選択するexercise . それから、それはコレクションを選びますworkouts で指定したquery . 返されるデータを配列に変換します.それから、すべてがうまく行ったなら、それは我々のコンソールにデータを記録します.プロセス中に何かが起きたら、コンソールで警告としてログ出力します.

    約束を返す機能を作るさま
    我々がMongoDBを使うならば、fetch または、約束を返すすべての機能は、我々はチェーンすることができますthen and catch それに対する方法とそれは、我々が約束で働くためにする必要があるすべてです.しかし、これは常にそうでありません.時々、最初に約束を返す関数を作成する必要があるかもしれません.
    たとえば、我々の演習データベースのために、我々はJavaScriptのためのAPIが約束を返さないいくつかのデータベースを使用することに決めたことを想像しましょう.代わりに、返されるデータを処理するコールバックを取る.だから我々は何かをしなければならないDbHandler.find(query, callback) 取得した情報で何かをしたいとき.コールバックが2つのパラメータをとることを想像しましょうdata and error , を返します.
    次に、データベース内のものを検索し、それを約束として返す関数を作成できます.
    const findPromise = query => new Promise((resolve, reject) => {
       DbHandler.find(query, (data, error) => {
          if (error == null) return resolve(data)
          else return reject(error)
       }
    })
    
    そして、我々が我々のデータベースのものを見たいならば、我々は約束を返す他のどんな機能のようにも我々の巧みに作られた機能を呼ぶことができます:
    findPromise(query)
       .then(doStuff)
       .catch(console.warn)