LoginSignup
4
7

More than 5 years have passed since last update.

非同期処理に同時実行数の制限を加えるthroat

Last updated at Posted at 2015-10-29

JavaScriptで読み上げ機能を実装したとき、同時に読み上げられると、聖徳太子にならなければ不便です。
また、クラウドテストで契約制限数以上のブラウザを起動しようとして、拒否されてテストが途中で落ちてしまう。

など、非同期処理に対して、1つずつ処理して欲しい場合や、5つ以下なら同時に実行しても良い。というケースがあると思います。

npm install throat bluebird --save

throatを利用することで、これらを簡潔に実装できます。1

babel-node quque.js
# task1...
# task1 done
# task2...
# task2 fail
# task3...
# task3 done
quque.js
import Promise from 'bluebird'
import throat from 'throat'

const delay= 100
const Queue= throat(Promise)(1)

Queue(()=>{
  console.log('task1...')
  return new Promise(resolve=>{
    setTimeout(()=>{
      console.log('task1 done')
      resolve()
    },delay)
  })
})
Queue(()=>{
  console.log('task2...')
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      console.log('task2 fail')
      reject()
    },delay)
  })
})
Queue(()=>{
  console.log('task3...')
  return new Promise(resolve=>{
    setTimeout(()=>{
      console.log('task3 done')
      resolve()
    },delay)
  })
})

上記の13に変更します。

babel-node parallel.js
# task1...
# task2...
# task3...
# task1 done
# task2 fail
# task3 done
import Promise from 'bluebird'
import throat from 'throat'

const delay= 100
const Parallel= throat(Promise)(3)

Parallel(()=>{
  console.log('task1...')
  return new Promise(resolve=>{
    setTimeout(()=>{
      console.log('task1 done')
      resolve()
    },delay)
  })
})
Parallel(()=>{
  console.log('task2...')
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      console.log('task2 fail')
      reject()
    },delay)
  })
})
Parallel(()=>{
  console.log('task3...')
  return new Promise(resolve=>{
    setTimeout(()=>{
      console.log('task3 done')
      resolve()
    },delay)
  })
})

throat(Promise)(3)の戻り値はファクトリ関数です。
特定のタスクにフックしたい場合、そのまま.thenを繋げます。

import Promise from 'bluebird'
import throat from 'throat'

const delay= 100
const Parallel= throat(Promise)(3)

let promise= Parallel(()=>{
  return new Promise((resolve,reject)=>{
    reject(new Error('だめです'))
  })
})

promise
.then(value=>{
  console.log(value)
})
.catch(reason=>{
  console.error(reason.message)
  process.exit(1)
})

  1. Promiseのporyfillを使用しなくても動作しますが、browserifyしたjsがIEで動作しないことに注意してください。 

4
7
1

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
4
7