RxJS各operators的marble圖
https://rxmarbles.com/
2019 ng conf
RXJS Operators in 20 minutes | Mike Brocchi & John Niedzwiecki
https://www.youtube.com/watch?v=ak3MvMn8u18&list=PLOETEcp3DkCpimylVKTDe968yNmNIajlR&index=48
[S05E06] RxJS 運算子全面解析
https://www.youtube.com/watch?v=DPyZq74V60o&list=PL9LUW6O9WZqgUMHwDsKQf3prtqVvjGZ6S&index=17
今天由Will保哥分享,很多時間是大家在想operator的實際應用
這一集片長2個小時,所以拆成2天po
投影片找不到,所以手搭一下第1頁
npm i -g webpack webpack-cli webpack-command lite-server typescript
npm init -y
tsc --init
npm i rxjs ts-loader typescript
mkdir src
mkdir src
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
let ob = of(1,2,3);
ob.pipe(map(v => v*5))
.subscribe(v => console.log(v));
html:5 snippet
<!DOCTYPE html>
<html lang="zh-Hant-TW"> 如果用en的話,chrome會跳出要不要翻譯
<head>
<meta charset="UTF-8">
<meta name="viewport content="width=device-width, initial-scale=1.0,
minimum-scale=1, maximum-scale=1">
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^避免手機的browser快速點2下就放大
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="dist/bundle.js"></script>
</head>
<body>
</body>
</html>
3.webpack.config.js
module.export = {
entry: {
vendor: "./src/index.ts"
},
mode: "development",
module: {
rules:[
{
test: /\.tsx?$/,
^^ tsx是react,?代表option 非必要,ts、tsx皆處理
loader: 'ts-loader'
}
]
},
plugins:[
],
output:{ 編譯到dist/bundle.js讓index.html引入
filename: "bundle.js",
},
resolve:{
extensions: ['.js','.jsx','.ts','.tsx']
},
}
以上設好環境就,就可以上路啦~
設不起來,用Angular專案也能玩
wp -w
lite-server # 存檔立刻看結果
以前都裝失敗,這一次竟然成功了,開心~
不知道跟wallaby有什麼不同?
VS Code 安裝 Quokka.js Extension
npm i -g typescript
npm init -y
tsc --init
npm i rxjs
index.js
import { of } from 'rxjs';
import { filter } from 'rxjs/operators';
// 1. of餵數列
var ob = of(1,2,3,4,5); // 建一個最簡單的observable
^^ 屬於建立observable的operator,直接把數列轉為observable
// 2. of餵array
var items = [1,2,3,4,5];
var ob2 = of(...items);
ob.subscribe((v) => {
console.log(v);
});
// 轉成observable後可以做很多操作,語法簡潔、語意好懂
// 範例1:做filter,用pipe再接operator
ob.pipe( // pipe是著跟observable的型別走,不用import
filter((v) => (v % 2 == 0)
)
後面的程式碼就打面斷囉
https://rxjs-dev.firebaseapp.com/api/index/function/fromEvent
把DOM EventTarget轉成Observable
轉成observable,再subject取得event的資料流後,就可以做超多事!!
fromEvent<T>(target: FromEventTarget<T>, eventName: string, options?: EventListenerOptions
^^^^^^^^^^^^^^^^^^ DOM EventTarget
| ((...args: any[]) => T), resultSelector?: ((...args: any[]) => T)): Observable<T>
// 最常用的就前面2個參數 target: FromEventTarget<T>, eventName: string
// 官網範例
import { fromEvent } from 'rxjs';
// 把document的click event轉成observable
const clicks$ = fromEvent(document, 'click');
^加$較好分辨 ^^^^^^^^ ^^^^^
clicks$.subscribe(x => console.log(x));
// MouseEvent
f MouseEvent() { [native code] }
^ 是一個function
// MouseEvent.__proto__
^^^^^^^^^ 上一層的object
f UIEvent() { [native code] }
^^^^^^^ 是UIEvent()
// MouseEvent.__proto__.__proto__ 上一層的上一層object
f Event() { [native code] }
// MouseEvent.__proto__.__proto__.__proto__
f() { [native code] }
// document
#document
// document.__proto__
HTMLDocument {constructor:f, Symbol(Symbol.toStringTag):"HTMLDocument"}
^^^^^^^^^^^^ 所有document都繼承HTMLDocument
// document.__proto__.__proto__
Document {...}
// document.__proto__.__proto__.__proto__
Node {ELEMENT_NODE:1, ATTRIBUTE_NODE:2, TEXT_NODE:3, ...}
^^^^ 一個網頁的節點
// document.__proto__.__proto__.__proto__.__proto__
EventTarget {addEventListener:f, removeEventListener:f, ...}
^^^^^^^^^^^ 所有DOM往上找都會有EventTarget
fromEvent<T>(target: FromEventTarget<T>,...
^^^^^^^^^^^ 所有型別都會有的EventTarget,就是指這個
// document.__proto__.__proto__.__proto__.__proto__.__proto__
{constructor:f, __defineGetter__:f, __defineSetter__:f,...}
(root)根物件
類似of(),差別在於from可以直接傳入array
from([10,20,30]
)
https://rxjs-dev.firebaseapp.com/api/index/function/from
Creates an Observable from an Array, an array-like object, a Promise
, an iterable object
, or an Observable-like object.
from<T>(input: ObservableInput<T>, scheduler?: SchedulerLike): Observable<T>
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
fromPromise()好像不見了,官網文件找不到
可能是RxJS6拿掉了,想看只能到舊文件找了
https://cn.rx.js.org/class/es6/Observable.js~Observable.html#static-method-fromPromise
var ob = from(fetch('data.json'));
^^^^^ fetch()可以用.json()轉json
// data.json {id:1, name:"Will"}
ob.pipe().subscribe((v:any)=>{
var ob2 = from(v.json());
^^^^^^^^ 回傳promise
ob2.subscribe((xx:any)=>{
console.log(xx.json());
})
});
然後… create()運算子也沒了…
變成Observable.create()
https://rxjs-dev.firebaseapp.com/api/index/function/bindCallback
傳入callback function,會自動把callback function轉成observable
Converts a callback API to a function that returns an Observable.
bindCallback<T>(callbackFunc: Function, resultSelector?: Function | SchedulerLike, scheduler?: SchedulerLike): (...args: any[]) => Observable<T>
官網範例
import { bindCallback } from 'rxjs';
import * as jQuery from 'jquery';
// Suppose we have jQuery.getJSON('/my/url', callback)
// 只要callbackFunc的signature用法是 ^^^^^^ 配 ^^^^^^ callback function
// 就可以用bindCallback來binding
const getJSONAsObservable = bindCallback(jQuery.getJSON);
^^^^^^^ 這是function
const result = getJSONAsObservable('/my/url');
result.subscribe(x => console.log(x), e => console.error(e));
https://rxjs-dev.firebaseapp.com/api/operators/repeat
Returns an Observable that will resubscribe to the source stream when the source stream completes, at most count times.
repeat<T>(count: number = -1): MonoTypeOperatorFunction<T>
^^^^^ 會重覆的subscribe n次
(a)--(b)--(complete)
如果count=3的話
會變成重覆3次
(a)--(b)--(a)--(b)--(a)--(b)--(complete)
https://rxjs-dev.firebaseapp.com/api/index/function/defer
Creates an Observable that, on subscribe, calls an Observable factory to make an Observable for each new Observer.
defer<R extends ObservableInput<any> | void>(observableFactory: () => R): Observable<ObservedValueOf<R>>
import { defer, fromEvent, interval } from 'rxjs';
const clicksOrInterval = defer(function () {
^^^^^^^^^^^ 放一個callback function
Observable factory
return Math.random() > 0.5
? fromEvent(document, 'click')
: interval(1000);
});
clicksOrInterval.subscribe(x => console.log(x));
^^^^^^^^^ 有observer訂閱的時候,就各別呼叫Observable factory
產生observable給observer