A pen test from Xunlei front end
Implement an EventEmitter class, and implement the following methods:
1.emitter.on(name,fn) / / subscribe to the name event. The listening function is fn. You can subscribe multiple times
2.emitter.once(name,fn) / / the function is similar to on, but the listening function is one-time, which is automatically removed after triggering
3. Emit. Emit (name, data1, data2,..., datan) / / publish the name event. All the listening functions subscribed to the event are triggered. data1,...,datan are passed to the listening functions as parameters. If there are multiple functions, they are executed in order
4.emitter.remove(name,fn) / / remove the listening function fn of the name event
Code implementation:
//Publish and subscribe mode function EventEmitter(){ //Cache list, store subscriber list var list = []; var instance; //Subscription event name,type = 0 for permanent subscription = 1 for primary subscription var on = function(name,fn,type = 0){ //Determine whether the event has been subscribed if(!list[name]){ list[name] = []; } list[name].push([fn,type]);//Listening function inserts the event list }; //Delete subscription once triggered var once = function(name,fn,type = 1){ on(name,fn,type); }; //Release var emit = function(name){ var fns = list[name];//Take out event //Get parameter list var args = [].slice.call(arguments,1); //Judge whether the listening function exists if (!fns || fns.length == 0) { return; } for(var i =0;i<fns.length,fn = fns[i++];){ fn[0].apply(this,args); if(fn[1] == 1){ remove(name,fn[0],1); } } }; //Delete event var remove = function(name,fn,type = 0){ if(!name){ return; } var fns = list[name]; //No listening function passed in, cancel all if(!fn){ list[name] = []; }else{ for(var i =0;i<fns.length,fn1 = fns[i];i++){ //Find the corresponding function and delete it if(fn === fn1[0]&&type ===fn1[1]){ fns.splice(i,1); } } } }; return { on:on, once:once, emit:emit, remove,remove } } var emitter = new EventEmitter(); var log = console.log; emitter.on('someTask',log); emitter.emit('someTask',1);//1 emitter.emit('someTask',1,2);//1,2 emitter.once('someTask',log); emitter.emit('someTask',1);//1 emitter.emit('onceTask',1);//No output emitter.remove('someTask',log); emitter.emit('someTask',1);//No output