Skip to content

Instantly share code, notes, and snippets.

@Ajido
Last active February 10, 2020 06:55
Show Gist options
  • Save Ajido/cf947bfde296f40b0a22d924b5298739 to your computer and use it in GitHub Desktop.
Save Ajido/cf947bfde296f40b0a22d924b5298739 to your computer and use it in GitHub Desktop.
const util = require('util')
const stream = require('stream')
const pipeline = util.promisify(stream.pipeline)
async function saveImage(rs, ws) {
await pipeline(rs, ws)
}
const util = require('util')
const stream = require('stream')
const finished = util.promisify(stream.finished)
async function saveImage(rs, ws) {
rs.pipe(ws)
await finished(ws)
}
// 課題1: for await のタイミングで readStream のエラーがハンドリングされるので、その前に readStream でエラーが発生すると捕捉漏れする
// * 権限のないファイルで stream を作成して、その stream の作成から for await までの間に非同期処理がある場合など
// 課題2: writeStream のエラーハンドリングができない
// 課題3: write の失敗に対応していない
async function saveImage(rs, ws) {
try {
for await (const data of rs) {
ws.write(data)
}
} catch (err) {
console.error(err)
} finally {
ws.end()
}
}
function saveImage(srcPath, dstPath) {
// stream を渡す形式だと P3-1 の問題が発生するので、ファイルパスを受け取る形式にして回避する
return new Promise((resolve, reject) => {
const src = fs.createReadStream(srcPath)
const dst = fs.createWriteStream(dstPath)
// pipe すると後続の stream にイベントが集約される
// readStream のエラーハンドリングは行わずにまず pipe してから error, finish などのイベントを捕捉する。P3-2 の対処
// https://stackoverflow.com/questions/21771220/error-handling-with-node-js-streams
src.pipe(dst).on('error', reject).on('finish', resolve)
// * 万が一ユーザーモジュールなどで stream のエラーが複数回発生すると 複数回 reject してしまうので、エラー回数を数えるべきでもある
// let rejected = false
// src.pipe(dst).on('error', (err) => {
// (rejected) ? console.error(err) : reject(err)
// rejected = true
// }).on('finish', resolve)
})
}
@Ajido
Copy link
Author

Ajido commented Feb 10, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment