JavaScriptの約束を理解する

Promiseは、コードにあまり多くのコールバックを記述せずに、JavaScriptで非同期コードを処理する1つの方法です。

約束の紹介

約束は一般的に次のように定義されます最終的に利用可能になる値のプロキシ

Promiseは、コードにあまり多くのコールバックを記述せずに、非同期コードを処理する1つの方法です。

それらは何年も前から存在していますが、標準化され、ES2015、そして今、それらはに取って代わられましたES2017沿って非同期関数

非同期関数promise APIをビルディングブロックとして使用するため、新しいコードでpromiseの代わりに非同期関数を使用する可能性がある場合でも、それらを理解することが基本です。

約束がどのように機能するか、簡単に言えば

約束が呼び出されると、それはで始まります保留状態。これは、呼び出し元関数が実行を継続し、promiseが独自の処理を実行するのを待って、呼び出し元関数にフィードバックを提供することを意味します。

この時点で、呼び出し元の関数は、promiseが返されるのを待ちます。解決された状態、または拒否された状態、 だが関数は、promiseが機能している間、実行を継続します

どのJSAPIの使用が約束されていますか?

独自のコードとライブラリコードに加えて、promiseは次のような標準の最新のWebAPIによって使用されます。

最新のJavaScriptでは、自分自身に気付く可能性はほとんどありません。ないpromiseを使用しているので、すぐにpromiseに飛び込みましょう。


約束を作成する

Promise APIは、を使用して初期化するPromiseコンストラクターを公開します。new Promise()

let done = true

const isItDoneYet = new Promise((resolve, reject) => { if (done) { const workDone = ‘Here is the thing I built’ resolve(workDone) } else { const why = ‘Still working on something else’ reject(why) } })

あなたが見ることができるように約束はチェックしますdoneグローバル変数。それがtrueの場合、解決されたpromiseを返します。それ以外の場合は、拒否されたpromiseを返します。

使用するresolveそしてreject値を返すことができます。上記の場合は文字列を返すだけですが、オブジェクトの場合もあります。


約束を消費する

前のセクションでは、Promiseがどのように作成されるかを紹介しました。

それでは、約束がどのようになるか見てみましょう消費または使用されます。

const isItDoneYet = new Promise()
//...

const checkIfItsDone = () => {
  isItDoneYet
    .then(ok => {
      console.log(ok)
    })
    .catch(err => {
      console.error(err)
    })
}

ランニングcheckIfItsDone()を実行しますisItDoneYet()約束し、それが解決するのを待ちます。thenコールバック、およびエラーがある場合、それはでそれを処理しますcatch折り返し電話。


チェーンの約束

約束を別の約束に戻し、約束のチェーンを作成することができます。

チェーンの約束の素晴らしい例は、フェッチAPI、XMLHttpRequest APIの上のレイヤー。これを使用して、リソースを取得し、リソースがフェッチされたときに実行するpromiseのチェーンをキューに入れることができます。

Fetch APIは、Promiseベースのメカニズムであり、fetch()を使用して独自の約束を定義することと同等ですnew Promise()

チェーンの約束の例

const status = response => {
  if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
  }
  return Promise.reject(new Error(response.statusText))
}

const json = response => response.json()

fetch(’/todos.json’) .then(status) .then(json) .then(data => { console.log(‘Request succeeded with JSON response’, data) }) .catch(error => { console.log(‘Request failed’, error) })

この例では、fetch()からTODOアイテムのリストを取得するにはtodos.jsonドメインルートでファイルが見つかり、promiseのチェーンを作成します。

ランニングfetch()を返します応答、これには多くのプロパティがあり、それらの中で参照します。

  • status、HTTPステータスコードを表す数値
  • statusText、ステータスメッセージ。OKリクエストが成功した場合

responseまた、json()メソッド。処理されて変換された本文のコンテンツで解決されるpromiseを返します。JSON

したがって、これらの前提を考えると、これが起こります。チェーンの最初の約束は、私たちが定義した、呼び出された関数です。status()、応答ステータスをチェックし、成功応答(200〜299)でない場合は、promiseを拒否します。

この操作により、promiseチェーンはリストされているすべてのチェーンされたpromiseをスキップし、に直接スキップします。catch()下部のステートメント、ログRequest failedエラーメッセージと一緒にテキスト。

代わりに成功した場合は、json()定義した関数。前の約束以来、成功したとき、responseオブジェクト、2番目のpromiseへの入力として取得します。

この場合、JSONで処理されたデータを返すため、3番目のpromiseはJSONを直接受け取ります。

.then((data) => {
  console.log('Request succeeded with JSON response', data)
})

それをコンソールに記録します。


エラーの処理

上記の例では、前のセクションで、catchそれは約束の連鎖に追加されました。

一連のプロミスのいずれかが失敗してエラーが発生するか、プロミスが拒否されると、制御は最も近いものに移動しますcatch()チェーンの下流のステートメント。

new Promise((resolve, reject) => {
  throw new Error('Error')
}).catch(err => {
  console.error(err)
})

// or new Promise((resolve, reject) => { reject(‘Error’) }).catch(err => { console.error(err) })

カスケードエラー

中にある場合catch()エラーが発生した場合は、2番目を追加できますcatch()それを処理するなど。

new Promise((resolve, reject) => {
  throw new Error('Error')
})
  .catch(err => {
    throw new Error('Error')
  })
  .catch(err => {
    console.error(err)
  })

オーケストレーションの約束

Promise.all()

異なるプロミスを同期する必要がある場合は、Promise.all()約束のリストを定義し、それらがすべて解決されたときに何かを実行するのに役立ちます。

例:

const f1 = fetch('/something.json')
const f2 = fetch('/something2.json')

Promise.all([f1, f2]) .then(res => { console.log(‘Array of results’, res) }) .catch(err => { console.error(err) })

ザ・ES2015破壊割り当て構文を使用すると、

Promise.all([f1, f2]).then(([res1, res2]) => {
  console.log('Results', res1, res2)
})

使用に限定されませんfetchもちろん、どんな約束も行くのは良いことです

Promise.race()

Promise.race()渡されたプロミスの1つが解決されるとすぐに実行され、添付されたコールバックが1回だけ実行され、最初のプロミスの結果が解決されます。

例:

const promiseOne = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one')
})
const promiseTwo = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two')
})

Promise.race([promiseOne, promiseTwo]).then(result => { console.log(result) // ‘two’ })

一般的なエラー

Uncaught TypeError:undefinedは約束ではありません

あなたが得るならUncaught TypeError: undefined is not a promiseコンソールのエラー、必ず使用してくださいnew Promise()ただの代わりにPromise()

私の無料ダウンロードJavaScriptビギナーズハンドブック


その他のjsチュートリアル: