Skip to content

Instantly share code, notes, and snippets.

@pjchender
Last active April 18, 2017 08:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjchender/c3fd1408b4fb1f8c0640c5c849672671 to your computer and use it in GitHub Desktop.
Save pjchender/c3fd1408b4fb1f8c0640c5c849672671 to your computer and use it in GitHub Desktop.
[JavaScript][RxJS] 30 天精通 RxJS (04): 什麼是 Observable ?
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}
/**
* 建立 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)
})
}
}
/**
* 建立 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)
})
}
// 建立物件實例
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!!')
@pjchender
Copy link
Author

pjchender commented Apr 17, 2017

[觀察者模式(Observer Pattern)]

觀念

觀察者模式簡單來說就是「我們可以對某件事註冊監聽,並在事件發生時,自動執行我們註冊的監聽者(listener)。」

檔案

檔案包含:createConstructorClass.js, createConstructorFunction.js, notify.js
Run on JSFiddle

參考資料

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

@pjchender
Copy link
Author

[Iterator Pattern]

觀念

  • Iterator Pattern 雖然很單純,但同時帶來了兩個優勢
    -- 第一它漸進式取得資料的特性可以拿來做延遲運算(Lazy evaluation),讓我們能用它來處理大資料結構。
    -- 第二因為 iterator 本身是序列,所以可以實作所有陣列的運算方法像 map, filter... 等!
  • 延遲運算(Lazy evaluation),或說 call-by-need ,是一種運算策略(evaluation strategy),簡單來說我們延遲一個表達式的運算時機直到真正需要它的值在做運算。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment