LoginSignup
0
0

More than 3 years have passed since last update.

【javascript】プロミス

Last updated at Posted at 2020-07-18

この記事は以下の書籍を参考にして執筆しました。

非同期処置

javascriptは最初から非同期言語

プロミスは未来の値を表すイブジェクト
プロミスの値がすでに取得されているなら、すぐに提供され、
まだなら値が取得できるまで待機できる。

これがコールバックなら、値がすでに取得されている場合、
もたもたしているとコールバックが呼び出されないことがある。

プロミス

プロミスは最終的なオブジェクトのこと
この最終的な(未来の)値にアクセスするにはプロミスでthenメソッドを呼び出してコールバック関数を渡す。

プロミスを使ってみる

fetch('https://qiita.com/')
  //アロー関数はリクエストが完了した後responseを使って呼び出される。
  .then(response => {
    //処理
  })

出典:入門JavaScriptプログラミング

プロミスが解決されたら、レスポンスオブジェクトからデータを取得する。

コールバックよりプロミスを使用したほうがコードが完結になる例を見てみる。

function getOrgs(usename) {
  return axios.get('https://example.com')
}

getOrgs('jisaacks').then(resp => {
  const orgs = resp.data
  //処理
})

プロミスを返す関数を作成し、従来のコールバックバージョンも書いてみる

function getOrgs(usename, callback) {
  return axios.get('https://example.com',callback)
}

getOrgs('jisaacks', resp => {
  const orgs = resp.data
  //処理
})

出典:入門JavaScriptプログラミング

コールバックバージョンだとgetOrgs関数がより複雑になっている。
というもの、axiosライブラリに渡すコールバック関数を受け取る必要があるため。

エラー処理

プロミスのthneメソッドの第2に引数にはエラーが発生したときに呼び出されるコールバックを渡せる。

function success(resp) {
  //成功時のレスポンスの処理
}

function error(err) {
  //エラー処理
}

const url = 'http://exmample.com'
axios.get(url).then(success, error)

出典:入門JavaScriptプログラミング

高度なプロミス

プ口ミスを作成する

プロミスを作成するには新しいPrimiseオブジェクトをインスタンス化する。
その際にはnew Promise(fn)のように引数として関数を指定する。

プロミスに渡される関数にはパラメータがつある

  1. プロミスを解決するための関数
  2. プロミスを拒否するための関数
const later = new Promice((resolve, reject) => {
  //何らかの非同期処理
  resolve('alligator')
})

later.then(response => {
  console.log(response) //alligator
})

出典:入門JavaScriptプログラミング

画像の読み込みをプロミスに変えたい場合、従来はこのようになるかもしれない

cosnt img = new Image()
img.onload = () => //画像が読み込まれたときの処理
img.onerror = () => //画像の読み込みが失敗したときの処理
img.srv = 'http://example.com'

出典:入門JavaScriptプログラミング

プロミスを使うとこうなる

function fetchImage(src) {
  return new Promise((res, rej) => {
    const img = new Image()
    img.onload = res
    img.onerror = rej
    img.src = src
  })
}

fetchImage('http:example.com').then(
  () => console.log('image loaded'),
  () => console.log('image failed')
)

出典:入門JavaScriptプログラミング

プロミス解決の前に5秒待機したい場合は

setTimeoutをプロミスでラッピングする

function wait(milliseconds) {
  return new Promise((resolve) => {
    setTimeout(resolve, milliseconds)
  })
}

wait(5000).then(() => {
  //5行後の処理
})

出典:入門JavaScriptプログラミング

入れ子のプロミス

fetchでは複数のプロミスを使用する必要がある。

fetch('http://example.com').then(resp => {
  resp.json().then(results => {
    //resultsを使って処理
  })
})

出典:入門JavaScriptプログラミング

プロミスではthenメソッドを呼び出すたびに、
新しいプロミスが返される。

これによりプロミスチェーンの作成ができる。

fetch('http://example.com')
  .then(resp => resp.json())
  .then(resultd => {
    //resultを使った処理
  })

出典:入門JavaScriptプログラミング

プロミスでthenメソッドを呼び出すときには
引数として関数を渡す

この関数から返されるものは何であっても
このチェーンの次のthenメソッドの値になる。

Promise.resolve(1)
  .then(number => number + 1) //1+1=2
  .then(number => number + 1) //2+1=3
  .then(number => number + 1) //3+1=4
  .then(number => {
    console.log(number) //4
  })

出典:入門JavaScriptプログラミング

アロー関数の注意

チェーンする際に以下はundefinedになる

Promise.resolve(1)
  .then(number => {
    number + 1
    console.log(number)
  }) 
  .then(number => {
    number + 1
    console.log(number)//undefined
  }) 
  .then(number => {
    number + 1
    console.log(number)//undefined
  }) 
  .then(number => {
    console.log(number) //undefined
  })

出典:入門JavaScriptプログラミング

アロー関数を使用する際にブロックを使うなら最後にretunして次のthenメソッドに値を渡す必要がある。

Promise.resolve(1)
  .then(number => {
    return number + 1
    console.log(number)//1+1=2
  }) 
  .then(number => {
    return number + 1
    console.log(number)//2+1=3
  }) 
  .then(number => {
    return number + 1
    console.log(number)//3+1=4
  }) 
  .then(number => {
    console.log(number) //4
  })

出典:入門JavaScriptプログラミング

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0