标签:parse 3.0.0 git util around hunk his mod exp
https://github.com/MetaMask/obs-store
ObservableStore
is a synchronous in-memory store for a single value, that you can subscribe to updates on
ObservableStore是一个内存中的可以订阅更新的同步存储,只存储一个值
const store = new ObservableStore(initState) store.subscribe(function showValue(value) { console.log(‘saw value:‘, value) })
//通过调用putState()来存储值 store.putState(5) // "saw value: 5" ,存储了5 store.putState(true) // "saw value: true" ,true覆盖了之前的5的值 store.putState({ hello: ‘world‘ }) // "saw value: { hello: ‘world‘ }" ,{ hello: ‘world‘ }覆盖了之前的true的值 console.log(store.getState().hello) // "world" ,通过调用getState()函数来得到存储的值
从上面的例子可以看出能且只能够存储一个值
Each ObservableStore
can be turned into an ObservableStoreStream
. An ObservableStoreStream
is a duplex stream that you can pipe new values into it or pipe its updated values out of it.
ObservableStore
可以转换成ObservableStoreStream
流,并且是一个双工流
Special behavior: Doesnt buffer outgoing updates, writes latest state to dest on pipe.
不缓冲输出更新,将最新状态写到管道dest上
const pipe = require(‘pump‘) const asStream = require(‘obs-store/lib/asStream‘) const storeOne = new ObservableStore(initState) const storeTwo = new ObservableStore() pipe(//相当于asStream(storeOne).pipe(transformStream).pipe(asStream(storeTwo)),而且使用pump监听错误 asStream(storeOne), transformStream, asStream(storeTwo) )
ObservableStore
are no longer streams. You can create streams via asStream
.
通过asStream
来创建ObservableStoreStream
流
obs-store/index.js
‘use strict‘ const extend = require(‘xtend‘) const EventEmitter = require(‘events‘) class ObservableStore extends EventEmitter { constructor (initState = {}) { super() // set init state this._state = initState } // wrapper around internal getState getState () {//输出值 return this._getState() } // wrapper around internal putState putState (newState) { this._putState(newState)//存储newState值 this.emit(‘update‘, newState)//并触发subscribe中的‘update‘事件,并调用相应的handler函数 } updateState (partialState) {//更改里面的一部分的值 // if non-null object, merge if (partialState && typeof partialState === ‘object‘) { const state = this.getState() const newState = Object.assign({}, state, partialState) this.putState(newState) // if not object, use new value } else { this.putState(partialState) } } // subscribe to changes subscribe (handler) { this.on(‘update‘, handler) } // unsubscribe to changes unsubscribe (handler) { this.removeListener(‘update‘, handler)//移除‘update‘事件 } // // private // // read from persistence _getState () { return this._state } // write to persistence _putState (newState) { this._state = newState } } module.exports = ObservableStore
其调用的lib库:
作用是将ObsStore转成ObsStoreStream流,并定义流相应的一些方法
const DuplexStream = require(‘stream‘).Duplex module.exports = asStream function asStream(obsStore) { return new ObsStoreStream(obsStore) } // // // // class ObsStoreStream extends DuplexStream { constructor(obsStore) { super({ // pass values, not serializations objectMode: true, }) // dont buffer outgoing updates this.resume() // save handler so we can unsubscribe later this.handler = (state) => this.push(state) // subscribe to obsStore changes this.obsStore = obsStore this.obsStore.subscribe(this.handler) } // emit current state on new destination pipe (dest, options) {//调用pipe函数,将obsStore.getState()值传到dest const result = DuplexStream.prototype.pipe.call(this, dest, options) dest.write(this.obsStore.getState()) return result } // write from incomming stream to state _write (chunk, encoding, callback) { this.obsStore.putState(chunk) callback() } // noop - outgoing stream is asking us if we have data we arent giving it _read (size) { } // unsubscribe from event emitter _destroy (err, callback) { this.obsStore.unsubscribe(this.handler); super._destroy(err, callback) } }
设置一个继承ObservableStore的LocalStorageStore,页面端的global.localStorage就是这个
‘use strict‘ const ObservableStore = require(‘../‘) class LocalStorageStore extends ObservableStore { constructor (opts = {}) { if (!global.localStorage) throw new Error(‘LocalStorageStore - can\‘t find localStorage.‘)//global.localStorage即浏览器本身是否有本地存储 super() this._storageKey = opts.storageKey if (!this._storageKey) throw new Error(‘LocalStorageStore - no storageKey specified.‘) } // // private // // read from persistence _getState () { const serialized = global.localStorage.getItem(this._storageKey)//不同的_storageKey对应的是本地存储的不同内容 return serialized ? JSON.parse(serialized) : undefined } // write to persistence _putState (newState) { const serialized = JSON.stringify(newState) return global.localStorage.setItem(this._storageKey, serialized) } } module.exports = LocalStorageStore
还有一些别的,但是先不管,之后用到再说
测试:
‘use strict‘ const test = require(‘tape‘)const pipe = streamUtils.pipeconst ObservableStore = require(‘../‘) const asStream = require(‘../lib/asStream‘) const TEST_WAIT = 200 test(‘basic stream‘, function(t){ t.plan(2) const initState = ‘init‘ const nextState = ‘next‘ const storeOne = new ObservableStore(initState)//在初始化时就存储值initState const storeTwo = new ObservableStore()//在初始化时并没有存储值 storeTwo.once(‘update‘, (value) => {//监听一次‘update‘事件 initValueCheck(value)//查看value值与initState值是否相同 storeTwo.once(‘update‘, nextValueCheck)//再监听一次查看与nextState的值是否相同 }) pipe(//将storeOne流中的值initState传给storeTwo流,storeTwo调用putState时会调用一次‘update‘事件,查看是否于initState值相同 asStream(storeOne), asStream(storeTwo) ) storeOne.putState(nextState)//将storeOne中的值从initState改变成nextState,这里又会触发一次‘update‘事件,这次是查看是否于nextState相同 function initValueCheck(value){ t.equal(value, initState, ‘storeTwo subscribed: state is initState‘) } function nextValueCheck(value){ t.equal(value, nextState, ‘storeTwo subscribed: state is nextState‘) } }) test(‘double stream‘, function(t){ t.plan(4) const initState = ‘init‘ const nextState = ‘next‘ const storeOne = new ObservableStore(initState) const storeTwo = new ObservableStore() storeTwo.once(‘update‘, (initValue) => { initValueCheck(‘storeTwo‘, initValue) storeTwo.once(‘update‘, (nextValue) => nextValueCheck(‘storeTwo‘, nextValue)) }) const storeThree = new ObservableStore() storeThree.once(‘update‘, (initValue) => { initValueCheck(‘storeThree‘, initValue) storeThree.once(‘update‘, (nextValue) => nextValueCheck(‘storeThree‘, nextValue)) }) pipe( asStream(storeOne), asStream(storeTwo)//storeTwo触发一次‘update‘ ) pipe( asStream(storeOne), asStream(storeThree)//storeThree触发一次‘update‘ ) storeOne.putState(nextState)//将会导致storeTwo、storeThree再分别触发一次 function initValueCheck(label, value){ t.equal(value, initState, `${label} subscribed: state is initState`) } function nextValueCheck(label, value){ t.equal(value, nextState, `${label} subscribed: state is nextState`) } })
LocalStorageStore的测试,首先localStorage是定义好的,并且是有storageKey值的,如{ storageKey: ‘test‘ }
‘use strict‘ const test = require(‘tape‘) const LocalStorageStore = require(‘../lib/localStorage‘) test(‘localStorage - localStorage presence validation‘, function(t){ t.plan(2) t.notOk(global.localStorage, ‘global.localStorage not defined‘) t.throws(() => { new LocalStorageStore({ storageKey: ‘test‘ }) }, Error, ‘throws error when localStorage is not defined‘) }) test(‘localStorage - storageKey validation‘, function(t){ t.plan(2) global.localStorage = createLocalStorage() t.ok(global.localStorage, ‘global.localStorage is defined‘) t.throws(() => { new LocalStorageStore() }, Error, ‘throws error when opts.storageKey is not defined‘) }) test(‘localStorage - basic test‘, function(t){ t.plan(2) global.localStorage = createLocalStorage() t.ok(global.localStorage, ‘global.localStorage is defined‘) const store = new LocalStorageStore({ storageKey: ‘test‘ }) store.putState(42) t.equal(store.getState(), 42, ‘store works roundtrips values great‘) }) test(‘localStorage - obj test‘, function(t){ t.plan(2) global.localStorage = createLocalStorage() t.ok(global.localStorage, ‘global.localStorage is defined‘) const store = new LocalStorageStore({ storageKey: ‘test‘ }) store.putState({ a: 123 }) t.deepEqual(store.getState(), { a: 123 }, ‘store works roundtrips obj values great‘) }) function createLocalStorage() { const values = {} const localStorage = {} localStorage.getItem = (key) => values[key] localStorage.setItem = (key, value) => values[key] = value return localStorage }
标签:parse 3.0.0 git util around hunk his mod exp
原文地址:https://www.cnblogs.com/wanghui-garcia/p/9885458.html