/** * Module dependencies. */ var make = require('./make') var Channel = require('./channel') /** * Expose `select`. */ module.exports = select /** * Return the first of the given channels with a value. * * @param {Function} channels... * @return {Function} * @api public */ function select(/*channels...*/) { var selectCh = make(arguments.length) var chans = [].slice.call(arguments, 0) // get all channels with values waiting var full = chans.filter(function (ch) { return ch.__chan.items.length + ch.__chan.pendingAdds.length > 0 }) // define get callback var get = function (err, value) { var args = arguments var ch = Channel.lastCalled // remove get callback from all selected channels chans.forEach(function (ch) { ch.__chan.removeGet(get) }) // add temporary selected yieldable function ch.selected = function (cb) { delete ch.selected cb.apply(null, args) } // added the selected channel to the select channel selectCh(null, ch) selectCh.close() } if (full.length > 1) { // multiple channels with waiting values, pick one at random full[Math.floor(Math.random() * full.length)](get) } else { // add get callback to all channels chans.forEach(function (ch) { ch(get) }) } return selectCh }