[JavaScript][RxJS] 30 天精通 RxJS (04): 什麼是 Observable ?
// 建立物件實例
const egghead = new Producer()
function listener1 (message) {
console.log(message + 'from listener1')
}
function listener2 (message) {
console.log(message + 'from listener2')
}
// 註冊監聽
egghead.addListener(listener1)
egghead.addListener(listener2)
// 當 notify 執行時,listener1 和 listener2 就會被通知
egghead.notify('A new Course!!')
/**
* 建立 Class:使用 function constructor
**/
function Producer() {
if(!(this instanceof Producer)){
// 如果 this 不是 Producer 的 instance(表示忘了用 "new")
throw new Error('Class constructor Producer cannot be invoked without "new"')
}
this.listeners = []
}
// 加入監聽的方法
Producer.prototype.addListener = function (listener) {
if (typeof listener === 'function') {
this.listeners.push(listener)
} else {
throw new Error('listener 必須是 function')
}
}
// 移除監聽的方法
Producer.prototype.removeListener = function (listener) {
this.listeners.splice(this.listeners.indexOf(listener), 1)
}
// 發送通知的方法
Producer.prototype.notify = function (message) {
this.listeners.forEach(listener => {
listener(message)
})
}
/**
* 建立 Class:使用 ES6 的 Class
**/
class Producer {
// constructor
constructor () {
this.listeners = []
}
// 加入監聽的方法
addListener (listener) {
if (typeof listener === 'function') {
this.listeners.push(listener)
} else {
throw new Error('listener 必須是 function')
}
}
// 加入移除的方法
removeListener (listener) {
this.listeners.splice(this.listeners.indexOf(listener), 1)
}
// 加入通知的方法
notify (message) {
this.listeners.forEach((listener) => {
listener(message)
})
}
}
const arr = [1, 2, 3]
// 原生的 array iterator
let nativeIterator = arr[Symbol.iterator]()
nativeIterator.next() // {value: 1, done: false}
nativeIterator.next() // {value: 2, done: false}
nativeIterator.next() // {value: 3, done: false}
nativeIterator.next() // {value: undefined, done: true}
// 利用 function 的方法建立 Array Iterator
function IteratorFromArray (arr) {
if (!(this instanceof IteratorFromArray)) {
throw new Error('請用 new IteratorFromArray( )')
}
this._array = arr
this._cursor = 0
}
// instance method
IteratorFromArray.prototype.next = function () {
return this._cursor < this._array.length ?
{ cursor: this._cursor, value: this._array[this._cursor++], done: false} :
{done: true}
}
let functionIterator = new IteratorFromArray(arr)
functionIterator.next() // {cursor: 0, value: 1, done: false}
functionIterator.next() // {cursor: 1, value: 2, done: false}
functionIterator.next() // {cursor: 2, value: 3, done: false}
functionIterator.next() // {done: true}
// 利用 ES6 class 建立 Iterator
class arrayIterator {
constructor (array) {
this._array = array
this._cursor = 0
}
// next function
next(){
return (this._cursor < this._array.length) ? {value: this._array[this._cursor++], done: false} : {done: true}
}
// map iterator
map(callback){
const iterator = new arrayIterator(this._array)
// return 一個物件,裡面包含 next 這個 method
return {
next(){
const { done, value } = iterator.next()
return {
done: done,
value: done ? undefined : callback(value)
}
}
}
}
}
let classIterator = new arrayIterator(arr)
let mapIterator = classIterator.map(value => value * 3)
classIterator.next() // {value: 1, done: false}
classIterator.next() // {value: 2, done: false}
classIterator.next() // {value: 3, done: false}
classIterator.next() // {done: true}
// use mapItertor
mapIterator.next() // {value: 3, done: false}
mapIterator.next() // {value: 6, done: false}
mapIterator.next() // {value: 9, done: false}
mapIterator.next() // {value: undefined, done: true}