
能力说明:
掌握计算机基础知识,初步了解Linux系统特性、安装步骤以及基本命令和操作;具备计算机基础网络知识与数据通信基础知识。
暂时未有相关云产品技术能力~
阿里云技能认证
详细说明我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
第一个示例 注册事件监听器的常规写法。 var button = document.querySelector('button'); button.addEventListener('click', () => console.log('Clicked!')); 使用 RxJS 的话,创建一个 observable 来代替(基于最新的Rxjs6版本写法) <script src='./lib/rxjs.6.3.3.umd.min.js'></script> <script> const { fromEvent } = rxjs; const button = document.querySelector('button'); fromEvent(button, 'click') .subscribe(() => console.log('Clicked!')); </script> 上面例子中的fromEvent就是基于Event 建立 Observable,fromEvent 的第一个参数要传入 DOM 对象,第二个参数传入要监听的事件名。 创建 Observable 有很多操作符 image.png 使用Create操作符从头开始创建一个Observable, 这个接收一个回调函数,把observer作为参数 // Observer 是一个对象,这个对象具有三个方法,分别是 next, error, complete // 建立 Observable 最简单方法是用 create 方法 // create 接收一个回调函数,把observer作为参数 const observer = { next: value => { console.log(`observer:` + value) }, error: error => { console.log('Error:', error); }, complete: () => { console.log('complete'); } } var observable = rxjs.Observable .create(observer => { observer.next('Jerry'); observer.next('Anna'); observer.complete(); observer.next('not work'); }) // 建立观察者来订阅 observable // 订阅一个 Observable 就像是执行一个 function observable.subscribe( observer ) 使用from操作符将对象、字符串,数组,promise 等其他类型转换为Observable,请自己敲一遍看结果。 const {from} = rxjs; function f() { return from(arguments); } const observer = { next: value => { console.log('Next: ' + value); }, error: error => { console.log('Error:', error); }, complete: () => { console.log('Complete'); } } // Array Like Object f(1, 2, 3).subscribe(observer); // string from('foo').subscribe(observer); // Set, any iterable object const s = new Set(['foo', window]); from(s).subscribe(observer); // Promise const source = from(new Promise((resolve, reject) => { setTimeout(() => { resolve('Hello RxJS!'); }, 3000) })) source.subscribe(observer);
Observable 和 数组都有filter, map 等运算操作operators,具体的区别是什么? 主要是两点: 延迟运算 渐进式取值 延迟运算 延迟运算很好理解,所有 Observable 一定会等到订阅后才开始对元素做运算,如果没有订阅就不会有运算的行为 var source = Rx.Observable.from([1,2,3,4,5]); var example = source.map(x => x + 1); 上面这段代码因为 Observable 还没有被订阅,所以不会真的对元素做运算,这跟数组的操作不一样,如下 var source = [1,2,3,4,5]; var example = source.map(x => x + 1); 上面这段代码执行完,example 就已经取得所有元素的返回值了。 数组的运算都必须完整的运算出每个元素的返回值并组成一个新数组,再做下一个运算。 渐进式取值 数组的 operators 都必须完整的运算出每个元素的返回值并组成一个数组,再做下一个 operator 的运算,我们看下面这段程式码 var source = [1,2,3]; var example = source .filter(x => x % 2 === 0) // 这裡会运算并返回一个完整的数组 .map(x => x + 1) // 这裡也会运算并返回一个完整的数组 上面这段代码,相信读者们都很熟悉了,大家应该都有注意到 source.filter(...)就会返回一整个新数组,再接下一个 operator 又会再返回一个新的数组,这一点其实在我们实作 map 跟 filter 时就能观察到 Array.prototype.map = function(callback) { var result = []; // 建立新数组 this.forEach(function(item, index, array) { result.push(callback(item, index, array)) }); return result; // 返回新数组 } 每一次的 operator 的运算都会建立一个新的数组,并在每个元素都运算完后返回这个新数组,我们可以用下面这张动态图表示运算过程 image.png Observable operator 的运算方式跟数组的是完全的不同,虽然 Observable 的 operator 也都会回传一个新的 observable,但因为元素是渐进式取得的关系,所以每次的运算是一个元素运算到底,而不是运算完全部的元素再返回。 var source = Rx.Observable.from([1,2,3]); var example = source .filter(x => x % 2 === 0) .map(x => x + 1) example.subscribe(console.log); 上面这段程式码运行的方式是这样的 送出 1 到 filter 被过滤掉 送出 2 到 filter 在被送到 map 转成 3,送到 observer console.log 印出 送出 3 到 filter 被过滤掉 每个元素送出后就是运算到底,在这个过程中不会等待其他的元素运算。这就是渐进式取值的特性,不知道读者们还记不记得我们在讲 Iterator 跟 Observer 时,就特别强调这两个 Pattern 的共同特性是渐进式取值,而我们在实作 Iterator 的过程中其实就能看出这个特性的运作方式 class IteratorFromArray { constructor(arr) { this._array = arr; this._cursor = 0; } next() { return this._cursor < this._array.length ? { value: this._array[this._cursor++], done: false } : { done: true }; } map(callback) { const iterator = new IteratorFromArray(this._array); return { next: () => { const { done, value } = iterator.next(); return { done: done, value: done ? undefined : callback(value) } } } } } var myIterator = new IteratorFromArray([1,2,3]); var newIterator = myIterator.map(x => x + 1); newIterator.next(); // { done: false, value: 2 } 虽然上面这段代码是一个非常简单的示范,但可以看得出来每一次 map 虽然都会返回一个新的 Iterator,但实际上在做元素运算时,因为渐进式的特性会使一个元素运算到底,Observable 也是相同的概念,我们可以用下面这张动态图表示运算过程 image.png 渐进式取值的观念在 Observable 中其实非常的重要,这个特性也使得 Observable 相较于 Array 的 operator 在做运算时来的高效很多,尤其是在处理大量资料的时候会非常明显! (想像一下我们今天要切五万个大蛋糕,你会选择切完一个请一个人拿走,还是全部切完再拿给所有人呢?哪个会比较有效率呢?)
Angular大量使用了JS的装饰器特性,先看 ruanyifeng的介绍 使用babel转换 步骤 : npm install -g babel-cli npm init; npm install --save-dev babel-plugin-transform-decorators-legacy babel --plugins transform-decorators-legacy 1.js > 1.es5.js 例1 @eat class Person { constructor() {} } function eat(target, key, descriptor) { console.log('吃饭'); console.log(target); console.log(key); console.log(descriptor); target.prototype.act = '我要吃饭'; } const jack = new Person(); console.log(jack.act); 转换后 var _class; let Person = eat(_class = class Person { constructor() {} }) || _class; function eat(target, key, descriptor) { console.log('吃饭'); console.log(target); console.log(key); console.log(descriptor); target.prototype.act = '我要吃饭'; } const jack = new Person(); console.log(jack.act); // 吃饭 // [Function: Person] // undefined // undefined // 我要吃饭 例2 function mixins(...list) { return function (target) { Object.assign(target.prototype, ...list); }; } const Foo = { foo() { console.log('foo') } }; @mixins(Foo) class MyClass {} let obj = new MyClass(); obj.foo() // "foo" babel 后 var _dec, _class; function mixins(...list) { return function (target) { Object.assign(target.prototype, ...list); }; } const Foo = { foo() { console.log('foo'); } }; let MyClass = (_dec = mixins(Foo), _dec(_class = class MyClass {}) || _class); let obj = new MyClass(); obj.foo(); // "foo"
最近再做新项目,前端用到的是angular6,自然绕不开rxjs。 可以把 RxJS 想成处理 非同步行为 的 Lodash。 搜了很多教程,发现有位台湾同胞写的30 天精通 RxJS系列非常好。由浅入深,循序渐进。 想学的同学可以直接去看。 而且简书的热心同学还翻译成了简体 另外谈谈个人对于学习新知识的方法。 首先对于陌生的技术名词要先去官方的网站看介绍,因为官方的教程是最新的,而且的写的人一般是技术的作者本人。 官方的教程一定要先多看几遍。 其次官方的教程可能写的比较晦涩,或者例子太少,这个时候可以搜些网友写的文章或者书籍看。 对于技术文章,要留意是否是转载,很多是不负责任的转载,没有加入自己的理解。 最后,对于编程光看是不行的,有时候看完感觉是会了,但是不看教程一行都敲不出来,这是因为思路是被别人引领着,自己没有在脑子里过一遍,建议看懂后自己再敲一便,也是理顺自己思路的过程。 动画的方式演示了大部分Rxjs的Operator的执行过程