ES6では、従来のネストされたコールバック構造による問題に対処するため、プロミス(Promise)オブジェクトが標準化されました。これは非同期オペレーションの完了または失敗を表現する仕組みです。
プロミスの基本構造
コンストラクタを通じてインスタンスを作成し、プロトタイプに.thenメソッドを持っています。スリーエスモジュールとして使用可能なライブラリを活用します。
$ npm install fs-promise
独立したファイル読み込み
以下のように複数の非同期処理を実行できますが、実行順序は保証されません。
import {readFile} from 'fs-promise'
const readFirst = readFile('./documents/a.txt', 'utf8')
.then(data => console.log('A:', data))
const readSecond = readFile('./documents/b.txt', 'utf8')
.then(data => console.log('B:', data))
const readThird = readFile('./documents/c.txt', 'utf8')
.then(data => console.log('C:', data))
チェーンによる連続処理
各.then呼び出しで新しいプロミスを返すことで、処理順序を保証しながら連鎖的な実行が可能になります。
import {readFile} from 'fs-promise'
readFile('./documents/a.txt', 'utf8')
.then(result => {
console.log('第一段階:', result)
return readFile('./documents/b.txt', 'utf8')
})
.then(result => {
console.log('第二段階:', result)
return readFile('./documents/c.txt', 'utf8')
})
.then(result => {
console.log('第三段階:', result)
})
例外処理の実装
.catchメソッドを使用すると、発生したエラーを単一の場所で処理できます。
import {readFile} from 'fs-promise'
readFile('./missing/file.txt', 'utf8')
.then(data => console.log(data))
.catch(error => {
console.error('読み取りエラー:', error.message)
})
部分的なエラー回復
特定のプロミスのみでエラーを捕捉することで、その後の連鎖処理が続行できるように制御可能です。
import {readFile} from 'fs-promise'
readFile('./invalid.txt', 'utf8')
.then(content => {
console.log('内容:', content)
return readFile('./next.txt', 'utf8')
})
.catch(err => {
console.warn('一部のエラー:', err.message)
return Promise.resolve('デフォルト値')
})
.then(finalValue => {
console.log('最終出力:', finalValue)
})
同時実行情報収集
複数の非同期タスクが完了するのを待って結果を取得する場合、プロミス.allメソッドが有効です。
import {readFile} from 'fs-promise'
const tasks = [
readFile('./files/first.txt', 'utf8'),
readFile('./files/second.txt', 'utf8'),
readFile('./files/third.txt', 'utf8')
]
Promise.all(tasks)
.then(results => {
results.forEach((item, index) => {
console.log(`ファイル${index + 1}:`, item)
})
})
.catch(failure => {
console.error('いずれかのコピーに失敗:', failure)
})
最速レスポンス優先
プロミス.raceは複数の操作中最も早く完了したものの結果を受け取ります。
import {readFile} from 'fs-promise'
const competingTasks = [
readFile('./source/fast.txt', 'utf8'),
readFile('./source/slow.txt', 'utf8'),
readFile('./source/stable.txt', 'utf8')
]
Promise.race(competingTasks)
.then(winners => {
console.log('最初に取得:', winners)
})
.catch(error => {
console.log('エラー発生:', error)
})