333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
 * 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
}