觀察者模式:
這是一種創建松散耦合代碼的技術。它定義對象間 一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將得到通知。由主體和觀察者組成,主體負責發布事件,同時觀察者通過訂閱這些事件來觀察該主體。主體并不知道觀察者的任何事情,觀察者知道主體并能注冊事件的回調函數。
node事件
<code>
server.on('connection', (stream) => {
console.log('someone connected!');
});
server.removeListener('connection', callback);
server.emit('connection', callback);
</code>
<p>
node 在一個事件里面只能注冊10個事件
</p>
實現它的功能
注冊與發布
<code>
function Events(name) {
this.name = name;
this._events = {};
}
Events.prototype.on = function(eventname, callback) {
if(this._events[eventname]) {
this._events[eventname].push(callback)
}else{
this._events[eventname]=[callback]
}
}
Events.prototype.emit=function(eventname){
var callbacks=this._events[eventname]
callbacks.forEach(function(callback){
callback()
})
}
var girl = new Events()
girl.on('長發及腰',function(){
console.log('長發及腰')
})
girl.on('長發及腰',function(){
console.log('長發及腰2')
})
girl.emit('長發及腰')
</code>
傳說是阿里面試題 實現效果
<code>
const emitter = new EventEmitter()
const sayHi = (name) => console.log(Hello ${name}
)
const sayHi2 = (name) => console.log(Good night, ${name}
)
emitter.on('hi', sayHi)
emitter.on('hi', sayHi2)
emitter.emit('hi', 'ScriptOJ')
// => Hello ScriptOJ
// => Good night, ScriptOJ
emitter.off('hi', sayHi)
emitter.emit('hi', 'ScriptOJ')
// => Good night, ScriptOJ
const emitter2 = new EventEmitter()
emitter2.on('hi', (name, age) => {
console.log(I am ${name}, and I am ${age} years old
)
})
emitter2.emit('hi', 'Jerry', 12)
// => I am Jerry, and I am 12 years old
</code>
實現它的功能
注冊與發布
<code>
function EventEmitter(name) {
this.name = name;
this._events = {};
}
EventEmitter.prototype.on = function(eventname, callback) {
if(this._events[eventname]) {
this._events[eventname].push(callback)
} else {
this._events[eventname] = [callback]
}
}
EventEmitter.prototype.emit = function(eventname) {
var args = Array.prototype.slice.call(arguments, 1)
var callbacks = this._events[eventname]
var self = this
callbacks.forEach(function(callback) {
callback.apply(self, args)
})
}
EventEmitter.prototype.off = function(eventname, callback) {
var callbacks = this._events[eventname]
let cbindex = callbacks.indexOf(callback)
if(cbindex === -1) {
console.log('沒有該方法')
} else {
callbacks.splice(cbindex, 1);
}
}
const emitter = new EventEmitter()
const sayHi = (name) => console.log(Hello ${name}
)
const sayHi2 = (name) => console.log(Good night, ${name}
)
emitter.on('hi', sayHi)
emitter.on('hi', sayHi2)
emitter.emit('hi', 'ScriptOJ')
Hello ScriptOJ
Good night, ScriptOJ
emitter.off('hi', sayHi)
emitter.off('hi', sayHi3)
emitter.emit('hi', 'ScriptOJ')
Good night, ScriptOJ
const emitter2 = new EventEmitter()
emitter2.on('hi', (name, age) => {
console.log(I am ${name}, and I am ${age} years old
)
})
emitter2.emit('hi', 'Jerry', 12)
</code>
ES6 class方法
<code>
class EventEmitter {
constructor(name) {
this.name = name;
this._events = {};
}
on(eventname, callback) {
if(this._events[eventname]) {
this._events[eventname].push(callback)
} else {
this._events[eventname] = [callback]
}
}
emit(eventname, ...args) {
let callbacks = this._events[eventname]
callbacks.forEach(function(callback) {
callback(args)
})
}
off(eventname,cb){
let callbacks = this._events[eventname];
let cbindex=callbacks.indexOf(cb)
if(cbindex===-1){
console.log('該方法不存在')
}else{
callbacks.splice(cbindex,1)
}
}
}
const emitter = new EventEmitter()
const sayHi = (name) => console.log(Hello ${name}
)
const sayHi2 = (name) => console.log(Good night, ${name}
)
emitter.on('hi', sayHi)
emitter.on('hi', sayHi2)
emitter.emit('hi', 'ScriptOJ')
emitter.off('hi', sayHi)
emitter.off('hi', 'sayHi3')
emitter.emit('hi', 'ScriptOJ')
const emitter2 = new EventEmitter()
emitter2.on('hi', (name, age) => {
console.log(I am ${name}, and I am ${age} years old
)
})
emitter2.emit('hi', 'Jerry', 12)</code>
redux 使用觀察模式代碼
<code>
let currentListeners = []
let nextListeners = currentListeners
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
function subscribe(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.')
}
//判斷是否是函數
let isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)
return function unsubscribe() {
if (!isSubscribed) {
return
}
isSubscribed = false
ensureCanMutateNextListeners()
const index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
}
}
每一次執行dispath 都會執行監聽函數
function dispatch(action) {
if (!isPlainObject(action)) {
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
}
if (typeof action.type === 'undefined') {
throw new Error(
'Actions may not have an undefined "type" property. ' +
'Have you misspelled a constant?'
)
}
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.')
}
try {
isDispatching = true
currentState = currentReducer(currentState, action)
} finally {
isDispatching = false
}
const listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
return action
}
</code>
總結,寫東西真累,以后會習慣的。。。