PJCHENder
4/17/2017 - 3:26 AM

[JavaScript][RxJS] 30 天精通 RxJS (04): 什麼是 Observable ?

[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}