UNPKG

3.06 kBJavaScriptView Raw
1// selector.js
2// A promise resolved when one of many promises resolves.
3//
4// 13/04/08, JHR, extracted from l8.js
5//
6"use strict";
7
8// This file adds methods to the l8 global object
9var l8 = require( "l8/lib/l8.js" )
10exports.l8 = l8
11
12function Selector( list, is_or ){
13 this.allPromises = list
14 this.firePromise = null
15 this.result = null
16 this.isOr = is_or // "Or" selectors ignore false results
17}
18var ProtoSelector = Selector.prototype
19
20l8.proto.selector = function( ll ){
21// L8#selector()
22// Make a selector promise, resolved when one of many promises resolves.
23 var list = (arguments.length === 1 && (ll instanceof Array)) ? ll : arguments
24 return new Selector( list)
25}
26
27// l8.any()
28// Alias for l8.selector()
29// See also l8.or()
30l8.proto.any = l8.proto.selector
31
32l8.proto.or = function( ll ){
33// L8#or()
34// Make a promise resolved when one of many promises resolves with thruth. If
35// one of the sub promises is rejected, the whole promise is rejected.
36// See also l8.any()
37 var list = (arguments.length === 1 && (ll instanceof Array)) ? ll : arguments
38 return new Selector( list, true)
39}
40
41l8.proto.select = function(){
42// l8#select()
43// Block task until one of many promises delivers.
44//
45// Usage:
46// l8.step( function(){
47// var timeout = l8.timeout( 1000 );
48// var read
49// fs.readFile( "xx", "utf8", read = l8.call( function( err, rslt ){
50// return [err,rslt]
51// });
52// l8.select( read, timeout )
53// }).step( function( err, rslt ){ if( err ){ ... }else{ ...use rslt... } )}
54//
55 var selector = new Selector( arguments)
56 return this.wait( selector )
57}
58
59ProtoSelector.__defineGetter__( "promise", function(){
60// A selector has a promise attached to itself.
61 var promise = this.firePromise
62 if( promise )return promise
63 var that = this
64 var list = this.allPromises
65 this.firePromise = promise = MakePromise()
66 var len = list.length
67 if( !len ){
68 promise.resolve( null)
69 return promise
70 }
71 var count = 0
72 function ok( r ){
73 if( !that.result ){
74 try{
75 while( r instanceof Function ){
76 r = r.call( l8)
77 }
78 }catch( e ){
79 return ko( e)
80 }
81 if( r.then ){
82 r.then( ok, ko)
83 }else{
84 count++
85 if( r || !that.isOr || count === len ){
86 that.result = that.isOr ? r : [null,r]
87 promise.resolve( that.result)
88 }
89 }
90 }
91 }
92 function ko( e ){
93 count++
94 if( !that.result ){
95 that.result = [e,null]
96 promise.resolve( that.result)
97 }
98 }
99 var item
100 var buf = []
101 for( var ii = 0 ; ii < len ; ii++ ){
102 item = list[ii]
103 while( item instanceof Function ){
104 item = item.call( l8)
105 }
106 if( item.then ){
107 buf.push( item)
108 }else{
109 ok( item)
110 return promise
111 }
112 }
113 if( len = buf.length ){
114 for( ii = 0 ; ii < len ; ii++ ){
115 item = buf[ii]
116 item.then( ok, ko)
117 }
118 }
119 return promise
120})
121
122ProtoSelector.then = function( callback, errback ){
123// A selector is also a promise.
124 return this.firePromise.then( callback, errback)
125}
126