From 09fd8603cb338286a1ded6040109a8b22225e79f Mon Sep 17 00:00:00 2001 From: h7ml Date: Tue, 25 Jun 2024 12:33:55 +0800 Subject: [PATCH 1/9] feat(docs): add Erlang cheat sheet (#673) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create an Erlang备忘清单 in markdown format to document common commands and operations for Erlang programming, including入门, 代码结构, 常用内置函数 (BIFs), 并发编程, 错误处理, 分布式编程, OTP框架, 和测试. This cheat sheet aims to provide a quick reference for Erlang developers and learners, summarizing key points and examples for various aspects of the language. --- docs/erlang.md | 251 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 docs/erlang.md diff --git a/docs/erlang.md b/docs/erlang.md new file mode 100644 index 00000000..a0473f2e --- /dev/null +++ b/docs/erlang.md @@ -0,0 +1,251 @@ +Erlang 备忘清单 +=== + +Erlang 是一种用于构建并发、分布式和容错系统的编程语言。以下是一些常用的命令和操作。 + +入门 +--- + +### 启动 Erlang Shell + +```shell +erl +``` + +### 编译代码 + +```shell +# 在 Erlang Shell 中编译 +c(module). +# 在命令行中编译 +erlc module.erl +``` + +### 运行代码 + +```shell +# 在 Erlang Shell 中运行 +module:function(). +# 从命令行运行 +erl -noshell -s module function -s init stop +``` + +### 退出 Erlang Shell + +```shell +q(). +``` + +代码结构 +--- + +### 模块定义 + +```erlang +-module(module_name). +-export([function_name/arity, ...]). + +function_name(Args) -> + % Function body. + Result. +``` + +### 导出函数 + +```erlang +-export([function1/0, function2/1]). +``` + +### 注释 + +```erlang +% 单行注释 +``` + +常用内置函数 (BIFs) +--- + +### 列表操作 + +```erlang +lists:append(List1, List2). +lists:map(Function, List). +lists:filter(Function, List). +lists:foldl(Function, Acc, List). +``` + +### 元组操作 + +```erlang +element(N, Tuple). +setelement(N, Tuple, Value). +tuple_size(Tuple). +``` + +### 字符串操作 + +```erlang +string:len(String). +string:concat(String1, String2). +string:tokens(String, Delimiters). +``` + +### 文件操作 + +```erlang +file:read_file(Filename). +file:write_file(Filename, Data). +file:delete(Filename). +``` + +并发编程 +--- + +### 创建进程 + +```erlang +Pid = spawn(Module, Function, Args). +``` + +### 发送消息 + +```erlang +Pid ! Message. +``` + +### 接收消息 + +```erlang +receive + Pattern1 -> Actions1; + Pattern2 -> Actions2; + ... +end. +``` + +### 链接进程 + +```erlang +link(Pid). +unlink(Pid). +``` + +### 监控进程 + +```erlang +MonitorRef = erlang:monitor(process, Pid). +erlang:demonitor(MonitorRef). +``` + +错误处理 +--- + +### 捕获异常 + +```erlang +try Expression of + Pattern -> Result +catch + Class:Reason -> Handler +end. +``` + +### 常见异常类型 + +- `throw` +- `error` +- `exit` + +分布式编程 +--- + +### 启动分布式节点 + +```shell +erl -name nodename@hostname -setcookie Cookie +``` + +### 连接节点 + +```erlang +net_adm:ping(Node). +``` + +### 发送消息到远程节点 + +```erlang +{remote_process, 'remote_node@host'} ! Message. +``` + +OTP 框架 +--- + +### 定义 GenServer + +```erlang +-module(my_gen_server). +-behaviour(gen_server). + +-export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). + +start_link() -> + gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). + +init([]) -> + {ok, #state{}}. + +handle_call(Request, From, State) -> + {reply, Reply, State}. + +handle_cast(Msg, State) -> + {noreply, State}. + +handle_info(Info, State) -> + {noreply, State}. + +terminate(Reason, State) -> + ok. + +code_change(OldVsn, State, Extra) -> + {ok, State}. +``` + +### 使用 GenServer + +```erlang +gen_server:start_link({local, Name}, Module, Args, Options). +gen_server:call(ServerRef, Request). +gen_server:cast(ServerRef, Msg). +``` + +测试 +--- + +### 编写 EUnit 测试 + +```erlang +-module(module_name_tests). +-include_lib("eunit/include/eunit.hrl"). + +simple_test() -> + ?assertEqual(Expected, Actual). + +complex_test_() -> + [ + {"Test case 1", ?_assertEqual(Expected1, Actual1)}, + {"Test case 2", ?_assertEqual(Expected2, Actual2)} + ]. +``` + +### 运行 EUnit 测试 + +```shell +# 在命令行中运行 +erl -eval "eunit:test(module_name)" -s init stop +``` + +另见 +--- + +- [Erlang 官方文档](https://www.erlang.org/docs) +- [Erlang 编程书籍](https://www.erlang.org/books) From 8f54901b92a526a9f59800cc8f0a40cc296857a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Jun 2024 04:35:11 +0000 Subject: [PATCH 2/9] doc: update CONTRIBUTING.md. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0b228509..1d36abc1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -341,6 +341,7 @@ jobs: LufsX baoer expoli +h7ml k23223 二丫讲梵 undefined @@ -349,7 +350,6 @@ jobs: 秋 雨落 Blossom 萌新杰少 -h7ml chaos YuRuiH Willxup From 121db975c4e18960aab8d97a3afe17dd85686f7c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Jun 2024 04:35:12 +0000 Subject: [PATCH 3/9] doc: update README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2eb52f98..c6fdcfd0 100644 --- a/README.md +++ b/README.md @@ -288,6 +288,7 @@ Quick Reference LufsX baoer expoli +h7ml k23223 二丫讲梵 undefined @@ -296,7 +297,6 @@ Quick Reference 秋 雨落 Blossom 萌新杰少 -h7ml chaos YuRuiH Willxup From 0be71ca830a7cbcc3785cd3a5e9adc697808aa44 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Tue, 25 Jun 2024 12:51:00 +0800 Subject: [PATCH 4/9] doc: update erlang.md #673 --- README.md | 1 + assets/erlang.svg | 12 ++++++++++++ docs/erlang.md | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 assets/erlang.svg diff --git a/README.md b/README.md index c6fdcfd0..f071af24 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ Quick Reference [Dockerfile](./docs/dockerfile.md) [Django](./docs/django.md) [Elixir](./docs/elixir.md) +[Erlang](./docs/erlang.md) [Flask](./docs/flask.md) [FastAPI](./docs/fastapi.md) [Flutter](./docs/flutter.md) diff --git a/assets/erlang.svg b/assets/erlang.svg new file mode 100644 index 00000000..a4b941c2 --- /dev/null +++ b/assets/erlang.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/erlang.md b/docs/erlang.md index a0473f2e..225c985a 100644 --- a/docs/erlang.md +++ b/docs/erlang.md @@ -1,7 +1,7 @@ Erlang 备忘清单 === -Erlang 是一种用于构建并发、分布式和容错系统的编程语言。以下是一些常用的命令和操作。 +[Erlang](https://www.erlang.org/) 是一种用于构建并发、分布式和容错系统的编程语言。以下是一些常用的命令和操作。 入门 --- From 942f2c9563ad24b9afc692903e221051bea836e9 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Tue, 25 Jun 2024 13:01:26 +0800 Subject: [PATCH 5/9] doc: update erlang.md #673 --- docs/erlang.md | 199 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/docs/erlang.md b/docs/erlang.md index 225c985a..26c473f7 100644 --- a/docs/erlang.md +++ b/docs/erlang.md @@ -13,6 +13,7 @@ erl ``` ### 编译代码 + ```shell # 在 Erlang Shell 中编译 @@ -22,6 +23,7 @@ erlc module.erl ``` ### 运行代码 + ```shell # 在 Erlang Shell 中运行 @@ -60,6 +62,148 @@ function_name(Args) -> ```erlang % 单行注释 +% 这是一个注释 +``` + +### 变量 + +```erlang +VarName = Value. % 变量名必须以大写字母开头 +Age = 25. +Name = "Alice". +``` + +数据类型 +--- + +### 原子 + +```erlang +atom. % 例子:atom, 'Atom with spaces' +``` + +### 数字 + +```erlang +123. % 整数 +3.14. % 浮点数 +``` + +### 布尔值 + +```erlang +true. +false. +``` + +### 字符串 + +```erlang +"Hello, World!". +``` + +### 元组 + +```erlang +{ok, "Success"}. +``` + +### 列表 + +```erlang +[1, 2, 3]. +[H|T] = [1, 2, 3]. % H = 1, T = [2, 3] +``` + +### 字典 (Map) + +```erlang +#{key1 => value1, key2 => value2}. +``` + +控制结构 +--- + +### 条件语句 + +```erlang +if + Condition1 -> Expression1; + Condition2 -> Expression2; + true -> DefaultExpression +end. +``` + +### case 表达式 + +```erlang +case Expression of + Pattern1 -> Expression1; + Pattern2 -> Expression2; + _ -> DefaultExpression +end. +``` + +### 函数定义 + +```erlang +% 无参函数 +my_function() -> + ok. + +% 有参函数 +add(A, B) -> + A + B. +``` + +列表操作 +--- + +### 列表生成 + +```erlang +% 生成 1 到 10 的列表 +[ X || X <- lists:seq(1, 10)]. + +% 生成 1 到 10 中的偶数 +[ X || X <- lists:seq(1, 10), X rem 2 == 0]. +``` + +并发 +--- + +### 启动进程 + +```erlang +spawn(Module, Function, Args). + +% 示例 +Pid = spawn(fun() -> io:format("Hello from process~n") end). +``` + +### 发送消息 + +```erlang +Pid ! Message. + +% 示例 +Pid ! {hello, self()}. +``` + +### 接收消息 + +```erlang +receive + Pattern1 -> Expression1; + Pattern2 -> Expression2; + after Timeout -> TimeoutExpression +end. +``` + +### 模式匹配 + +```erlang +{ok, Value} = {ok, 42}. ``` 常用内置函数 (BIFs) @@ -98,6 +242,51 @@ file:write_file(Filename, Data). file:delete(Filename). ``` +### 列表操作 + +```erlang +lists:map(fun(X) -> X * 2 end, [1, 2, 3]). +lists:filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). +``` + +### 字符串操作 + +```erlang +string:len("Hello"). +string:upper("hello"). +``` + +### 文件操作 + +```erlang +{ok, File} = file:open("test.txt", [write]). +file:write(File, "Hello, file!"). +file:close(File). +``` + +### 示例:简单的服务器 + +```erlang +-module(server). +-export([start/0, loop/0]). + +start() -> + spawn(fun loop/0). + +loop() -> + receive + {echo, Msg} -> + io:format("Echo: ~p~n", [Msg]), + loop(); + stop -> + io:format("Server stopping~n"), + ok; + _ -> + io:format("Unknown message~n"), + loop() + end. +``` + 并发编程 --- @@ -156,6 +345,16 @@ end. - `error` - `exit` +### 错误处理 + +```erlang +try Expression of + Pattern -> Result +catch + Type:Reason -> ErrorHandlingExpression +end. +``` + 分布式编程 --- From 1013713630d4da15a5d98645674e7f03fa795579 Mon Sep 17 00:00:00 2001 From: h7ml Date: Tue, 25 Jun 2024 13:05:27 +0800 Subject: [PATCH 6/9] doc: add rxjs.md cheat sheet (#674) Create a new cheat sheet for RxJS covering key concepts, operators, and methods. This includes installation, importing, creating Observables, and using various operators such as map, filter, switchMap, and more. The document also explains important concepts like Schedulers and provides examples for better understanding. --- docs/rxjs.md | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 docs/rxjs.md diff --git a/docs/rxjs.md b/docs/rxjs.md new file mode 100644 index 00000000..57f1d9bb --- /dev/null +++ b/docs/rxjs.md @@ -0,0 +1,298 @@ +RxJS 备忘清单 +=== + +RxJS(Reactive Extensions for JavaScript)是一个强大的库,用于处理异步事件和数据流。以下是 RxJS 的一些关键概念、操作符和方法的总结。 + +## 入门 + +### 安装 RxJS + +```bash +npm install rxjs +``` + +### 导入所需的 Observable 和操作符 + +```javascript +import { Observable, of, from, interval, fromEvent } from 'rxjs'; +import { + map, + filter, + switchMap, + mergeMap, + catchError, + debounceTime, + distinctUntilChanged, + take, + tap, + concatMap, + delay, + retryWhen, + scan, + combineLatest, + concat, + merge, + forkJoin, + withLatestFrom, + startWith, + reduce +} from 'rxjs/operators'; +``` + +## 创建 Observable + +### of - 创建一个立即发送指定值并完成的 Observable + +```javascript +const obs = of(1, 2, 3); +obs.subscribe(console.log); +// 输出: 1 2 3 +``` + +### from - 从 Promise、数组、可迭代对象创建 Observable + +```javascript +const obs = from([1, 2, 3]); +obs.subscribe(console.log); +// 输出: 1 2 3 +``` + +### interval - 创建一个定时发送递增整数的 Observable + +```javascript +const obs = interval(1000); +obs.subscribe(console.log); +// 每秒输出一次递增的数字 +``` + +### fromEvent - 从 DOM 事件创建 Observable + +```javascript +const button = document.querySelector('button'); +const obs = fromEvent(button, 'click'); +obs.subscribe(event => console.log('Button clicked!', event)); +``` + +## 操作符 + +### map - 对 Observable 发出的每个值应用一个函数 + +```javascript +const obs = of(1, 2, 3).pipe( + map(x => x * 2) +); +obs.subscribe(console.log); +// 输出: 2 4 6 +``` + +### filter - 过滤 Observable 发出的值 + +```javascript +const obs = of(1, 2, 3).pipe( + filter(x => x % 2 === 0) +); +obs.subscribe(console.log); +// 输出: 2 +``` + +### switchMap - 将 Observable 每个值映射成 Observable 并订阅,前一个订阅将被取消 + +```javascript +const obs = interval(1000).pipe( + switchMap(() => of('Hello')) +); +obs.subscribe(console.log); +// 每秒输出一次 "Hello" +``` + +### mergeMap - 类似 switchMap,但允许多个内部 Observable 并发执行 + +```javascript +const obs = interval(1000).pipe( + mergeMap(() => of('Hello')) +); +obs.subscribe(console.log); +// 每秒输出一次 "Hello" +``` + +### catchError - 捕获 Observable 链中的错误 + +```javascript +const obs = of(1, 2, 3).pipe( + map(x => { + if (x === 2) throw 'Error!'; + return x; + }), + catchError(err => of('Caught an error: ' + err)) +); +obs.subscribe(console.log); +// 输出: 1 Caught an error: Error! +``` + +### debounceTime - 延迟处理,直到源 Observable 停止发出数据一定时间 + +```javascript +const obs = fromEvent(document, 'mousemove').pipe( + debounceTime(300) +); +obs.subscribe(event => console.log('Mouse moved!', event)); +``` + +### distinctUntilChanged - 忽略连续重复的值 + +```javascript +const obs = of(1, 1, 2, 2, 3, 3).pipe( + distinctUntilChanged() +); +obs.subscribe(console.log); +// 输出: 1 2 3 +``` + +### take - 只发出前 n 个值 + +```javascript +const obs = interval(1000).pipe( + take(3) +); +obs.subscribe(console.log); +// 输出: 0 1 2 +``` + +## 组合操作符 + +### combineLatest - 当两个 Observable 都发出新的值时,发出它们的组合 + +```javascript +const obs1 = interval(1000); +const obs2 = of('A', 'B', 'C'); +const combined = combineLatest([obs1, obs2]); +combined.subscribe(console.log); +// 每秒输出一次两个 observables 的最新值 +``` + +### concat - 按顺序连接多个 Observable + +```javascript +const obs1 = of(1, 2, 3); +const obs2 = of(4, 5, 6); +const combined = concat(obs1, obs2); +combined.subscribe(console.log); +// 输出: 1 2 3 4 5 6 +``` + +### merge - 将多个 Observable 合并为一个 + +```javascript +const obs1 = interval(1000).pipe(map(x => 'A' + x)); +const obs2 = interval(500).pipe(map(x => 'B' + x)); +const combined = merge(obs1, obs2); +combined.subscribe(console.log); +// 每秒输出 "A" 和 "B" 开头的递增数字 +``` + +### forkJoin - 等待所有 Observable 完成,然后发出它们的最后一个值的数组 + +```javascript +const obs1 = of(1, 2, 3); +const obs2 = of('A', 'B', 'C'); +const combined = forkJoin([obs1, obs2]); +combined.subscribe(console.log); +// 输出: [3, 'C'] +``` + +## 错误处理 + +### retryWhen - 在 Observable 发出错误时重试 + +```javascript +const obs = throwError('Something went wrong!').pipe( + retryWhen(errors => + errors.pipe( + delayWhen(() => interval(1000)) + ) + ) +); +obs.subscribe(console.log, console.error); +// 输出: Something went wrong! (每秒重试一次) +``` + +## 实用操作符 + +### tap - 用于记录、测量或执行副作用操作 + +```javascript +const obs = of(1, 2, 3).pipe( + tap(x => console.log(`Before: ${x}`)), + map(x => x * 2), + tap(x => console.log(`After: ${x}`)) +); +obs.subscribe(); +// 输出: Before: 1, After: 2, Before: 2, After: 4, Before: 3, After: 6 +``` + +### startWith - 在 Observable 序列前添加值 + +```javascript +const obs = of(1, 2, 3).pipe( + startWith(0) +); +obs.subscribe(console.log); +// 输出: 0 1 2 3 +``` + +### scan - 对 Observable 发出的每个值应用累加器函数 + +```javascript +const obs = of(1, 2, 3).pipe( + scan((acc, value) => acc + value, 0) +); +obs.subscribe(console.log); +// 输出: 1 3 6 +``` + +### reduce - 对 Observable 发出的值进行累加 + +```javascript +const obs = of(1, 2, 3).pipe( + reduce((acc, value) => acc + value, 0) +); +obs.subscribe(console.log); +// 输出: 6 +``` + +### delay - 延迟 Observable 发出数据的时间 + +```javascript +const obs = of('Hello').pipe( + delay(2000) +); +obs.subscribe(console.log); +// 输出: 'Hello' (延迟2秒) +``` + +## 调度器 + +调度器(Scheduler)控制着 RxJS 操作的执行时机。常见的调度器有: + +- `asyncScheduler`:异步执行任务。 +- `queueScheduler`:按队列顺序执行任务。 +- `animationFrameScheduler`:在浏览器的下一次重绘前执行任务。 + +### 示例 + +```javascript +const obs = of(1, 2, 3).pipe( + observeOn(asyncScheduler) +); + +console.log('Before subscribe'); +obs.subscribe(console.log); +console.log('After subscribe'); +// 输出: Before subscribe, After subscribe, 1, 2, 3 +``` + +## 另见 + +- [RxJS 官方文档](https://rxjs.dev/) +- [RxJS 学习资源](https://rxjs.dev/guide/overview) +- [RxJS 操作符参考](https://rxjs.dev/guide/operators) From 99c34277e11a4257af9fb6bc0cc263eb80022ec8 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Tue, 25 Jun 2024 13:52:13 +0800 Subject: [PATCH 7/9] doc: update xjs.md #674 --- README.md | 3 +- assets/rxjs.svg | 27 +++++ docs/rxjs.md | 273 ++++++++++++++++++++++++++++++++++-------------- 3 files changed, 226 insertions(+), 77 deletions(-) create mode 100644 assets/rxjs.svg diff --git a/README.md b/README.md index f071af24..1c1dda88 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Quick Reference [Scala](./docs/scala.md) [Swift](./docs/swift.md) [SwiftUI](./docs/swiftui.md) -[Spring Boot](./docs/springboot.md) +[Spring Boot](./docs/springboot.md) [Lua](./docs/lua.md) [Pytorch](./docs/pytorch.md) @@ -101,6 +101,7 @@ Quick Reference [JavaScript](./docs/javascript.md) [jQuery](./docs/jquery.md) [Next.js](./docs/nextjs.md) +[RxJS](./docs/rxjs.md) [React](./docs/react.md) [React Router](./docs/reactrouter.md) [React Native](./docs/react-native.md) diff --git a/assets/rxjs.svg b/assets/rxjs.svg new file mode 100644 index 00000000..8cde0f51 --- /dev/null +++ b/assets/rxjs.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/rxjs.md b/docs/rxjs.md index 57f1d9bb..d19ec882 100644 --- a/docs/rxjs.md +++ b/docs/rxjs.md @@ -1,7 +1,7 @@ RxJS 备忘清单 === -RxJS(Reactive Extensions for JavaScript)是一个强大的库,用于处理异步事件和数据流。以下是 RxJS 的一些关键概念、操作符和方法的总结。 +[RxJS](https://rxjs.dev/)(Reactive Extensions for JavaScript)是一个强大的库,用于处理异步事件和数据流。以下是 RxJS 的一些关键概念、操作符和方法的总结。 ## 入门 @@ -11,37 +11,100 @@ RxJS(Reactive Extensions for JavaScript)是一个强大的库,用于处理 npm install rxjs ``` +### 清晰 + + +RxJS 的强大之处在于它使用纯函数生成值的能力。这意味着您的代码更不容易出错。通常情况下,您会创建一个不纯的函数,而代码的其他部分可能会弄乱您的状态。 + +```js +let count = 0; +document.addEventListener('click', () => { + console.log(`Clicked ${++count} times`) +}); +``` + +使用 RxJS 可以隔离状态。 + +```js +import { fromEvent, scan } from 'rxjs'; + +fromEvent(document, 'click') + .pipe(scan((count) => count + 1, 0)) + .subscribe((count) => { + console.log(`Clicked ${count} times`) + }); +``` + +扫描操作符的工作原理与数组的 `reduce` 类似。它接受一个暴露给回调函数的值。回调的返回值将成为下次回调运行时公开的下一个值。 + +### 流 + + +RxJS 拥有一整套运算符,可以帮助您控制事件如何流经您的可观察对象。这是使用纯 JavaScript 每秒最多允许一次点击的方式: + +```js +let count = 0; +let rate = 1000; +let lastClick = Date.now() - rate; +document.addEventListener('click', () => { + if (Date.now() - lastClick >= rate) { + console.log(`Clicked ${++count}times`); + lastClick = Date.now(); + } +}); +``` + +使用 RxJS: + +```js +import { fromEvent, throttleTime, scan + } from 'rxjs'; + +fromEvent(document, 'click') + .pipe(throttleTime(1000), + scan((count) => count + 1, 0) + ) + .subscribe((count) => { + console.log(`Clicked ${count} times`) + }); +``` + +### 第一个示例 + +通常情况下,您需要注册事件监听器。 + +```js +document.addEventListener('click', () => { + console.log('Clicked!') +}); +``` + +使用 [RxJS](https://rxjs.dev/),您可以创建一个可观察对象。 + +```js +import { fromEvent } from 'rxjs'; + +fromEvent(document, 'click') + .subscribe(() => { + console.log('Clicked!') + }); +``` + ### 导入所需的 Observable 和操作符 + ```javascript import { Observable, of, from, interval, fromEvent } from 'rxjs'; -import { - map, - filter, - switchMap, - mergeMap, - catchError, - debounceTime, - distinctUntilChanged, - take, - tap, - concatMap, - delay, - retryWhen, - scan, - combineLatest, - concat, - merge, - forkJoin, - withLatestFrom, - startWith, - reduce + +import { map, filter, switchMap, mergeMap, catchError, debounceTime, + distinctUntilChanged, take, tap, concatMap, delay, retryWhen, scan, + combineLatest, concat, merge, forkJoin, withLatestFrom, startWith, reduce } from 'rxjs/operators'; ``` ## 创建 Observable -### of - 创建一个立即发送指定值并完成的 Observable +### of ```javascript const obs = of(1, 2, 3); @@ -49,7 +112,9 @@ obs.subscribe(console.log); // 输出: 1 2 3 ``` -### from - 从 Promise、数组、可迭代对象创建 Observable +创建一个立即发送指定值并完成的 Observable + +### from ```javascript const obs = from([1, 2, 3]); @@ -57,7 +122,9 @@ obs.subscribe(console.log); // 输出: 1 2 3 ``` -### interval - 创建一个定时发送递增整数的 Observable +从 Promise、数组、可迭代对象创建 Observable + +### interval ```javascript const obs = interval(1000); @@ -65,17 +132,24 @@ obs.subscribe(console.log); // 每秒输出一次递增的数字 ``` -### fromEvent - 从 DOM 事件创建 Observable +创建一个定时发送递增整数的 Observable + +### fromEvent + ```javascript const button = document.querySelector('button'); const obs = fromEvent(button, 'click'); -obs.subscribe(event => console.log('Button clicked!', event)); +obs.subscribe(event => { + console.log('Button clicked!', event) +}); ``` +从 DOM 事件创建 Observable + ## 操作符 -### map - 对 Observable 发出的每个值应用一个函数 +### map ```javascript const obs = of(1, 2, 3).pipe( @@ -85,7 +159,9 @@ obs.subscribe(console.log); // 输出: 2 4 6 ``` -### filter - 过滤 Observable 发出的值 +对 Observable 发出的每个值应用一个函数 + +### filter ```javascript const obs = of(1, 2, 3).pipe( @@ -95,27 +171,35 @@ obs.subscribe(console.log); // 输出: 2 ``` -### switchMap - 将 Observable 每个值映射成 Observable 并订阅,前一个订阅将被取消 +过滤 Observable 发出的值 + +### switchMap ```javascript const obs = interval(1000).pipe( switchMap(() => of('Hello')) ); + obs.subscribe(console.log); // 每秒输出一次 "Hello" ``` -### mergeMap - 类似 switchMap,但允许多个内部 Observable 并发执行 +将 Observable 每个值映射成 Observable 并订阅,前一个订阅将被取消 + +### mergeMap ```javascript const obs = interval(1000).pipe( mergeMap(() => of('Hello')) ); + obs.subscribe(console.log); // 每秒输出一次 "Hello" ``` -### catchError - 捕获 Observable 链中的错误 +类似 switchMap,但允许多个内部 Observable 并发执行 + +### catchError ```javascript const obs = of(1, 2, 3).pipe( @@ -123,22 +207,28 @@ const obs = of(1, 2, 3).pipe( if (x === 2) throw 'Error!'; return x; }), - catchError(err => of('Caught an error: ' + err)) + catchError(err => of('发现一个错误:'+err)) ); obs.subscribe(console.log); -// 输出: 1 Caught an error: Error! +// 输出: 1 发现一个错误:Error! ``` -### debounceTime - 延迟处理,直到源 Observable 停止发出数据一定时间 +捕获 Observable 链中的错误 + +### debounceTime ```javascript -const obs = fromEvent(document, 'mousemove').pipe( - debounceTime(300) -); -obs.subscribe(event => console.log('Mouse moved!', event)); +const obs = fromEvent(document,'mousemove') + .pipe(debounceTime(300)); + +obs.subscribe(event => { + console.log('Mouse moved!', event) +}); ``` -### distinctUntilChanged - 忽略连续重复的值 +延迟处理,直到源 Observable 停止发出数据一定时间 + +### distinctUntilChanged ```javascript const obs = of(1, 1, 2, 2, 3, 3).pipe( @@ -148,7 +238,9 @@ obs.subscribe(console.log); // 输出: 1 2 3 ``` -### take - 只发出前 n 个值 +忽略连续重复的值 + +### take ```javascript const obs = interval(1000).pipe( @@ -158,19 +250,26 @@ obs.subscribe(console.log); // 输出: 0 1 2 ``` +只发出前 n 个值 + ## 组合操作符 -### combineLatest - 当两个 Observable 都发出新的值时,发出它们的组合 +### combineLatest ```javascript const obs1 = interval(1000); const obs2 = of('A', 'B', 'C'); -const combined = combineLatest([obs1, obs2]); +const combined = combineLatest( + [obs1, obs2] +); + combined.subscribe(console.log); // 每秒输出一次两个 observables 的最新值 ``` -### concat - 按顺序连接多个 Observable +当两个 Observable 都发出新的值时,发出它们的组合 + +### concat ```javascript const obs1 = of(1, 2, 3); @@ -180,17 +279,25 @@ combined.subscribe(console.log); // 输出: 1 2 3 4 5 6 ``` -### merge - 将多个 Observable 合并为一个 +按顺序连接多个 Observable + +### merge ```javascript -const obs1 = interval(1000).pipe(map(x => 'A' + x)); -const obs2 = interval(500).pipe(map(x => 'B' + x)); +const obs1 = interval(1000).pipe( + map(x => 'A' + x) +); +const obs2 = interval(500).pipe( + map(x => 'B' + x) +); const combined = merge(obs1, obs2); combined.subscribe(console.log); // 每秒输出 "A" 和 "B" 开头的递增数字 ``` -### forkJoin - 等待所有 Observable 完成,然后发出它们的最后一个值的数组 +将多个 Observable 合并为一个 + +### forkJoin ```javascript const obs1 = of(1, 2, 3); @@ -200,25 +307,29 @@ combined.subscribe(console.log); // 输出: [3, 'C'] ``` +等待所有 Observable 完成,然后发出它们的最后一个值的数组 + ## 错误处理 -### retryWhen - 在 Observable 发出错误时重试 +### retryWhen + ```javascript -const obs = throwError('Something went wrong!').pipe( - retryWhen(errors => - errors.pipe( - delayWhen(() => interval(1000)) - ) - ) -); +const obs = throwError('出了些问题!') + .pipe( + retryWhen(errors => + errors.pipe(delayWhen(() => interval(1000))) + ) + ); obs.subscribe(console.log, console.error); -// 输出: Something went wrong! (每秒重试一次) +// 输出: 出了些问题! (每秒重试一次) ``` +在 Observable 发出错误时重试 + ## 实用操作符 -### tap - 用于记录、测量或执行副作用操作 +### tap ```javascript const obs = of(1, 2, 3).pipe( @@ -227,10 +338,13 @@ const obs = of(1, 2, 3).pipe( tap(x => console.log(`After: ${x}`)) ); obs.subscribe(); -// 输出: Before: 1, After: 2, Before: 2, After: 4, Before: 3, After: 6 +// 输出: Before: 1, After: 2, Before: 2, +// After: 4, Before: 3, After: 6 ``` -### startWith - 在 Observable 序列前添加值 +用于记录、测量或执行副作用操作 + +### startWith ```javascript const obs = of(1, 2, 3).pipe( @@ -240,7 +354,9 @@ obs.subscribe(console.log); // 输出: 0 1 2 3 ``` -### scan - 对 Observable 发出的每个值应用累加器函数 +在 `Observable` 序列前添加值 + +### scan ```javascript const obs = of(1, 2, 3).pipe( @@ -250,40 +366,45 @@ obs.subscribe(console.log); // 输出: 1 3 6 ``` -### reduce - 对 Observable 发出的值进行累加 +对 `Observable` 发出的每个值应用累加器函数 + +### reduce + ```javascript -const obs = of(1, 2, 3).pipe( - reduce((acc, value) => acc + value, 0) -); +const obs = of(1, 2, 3).pipe(reduce((acc, value) => acc + value, 0)); obs.subscribe(console.log); // 输出: 6 ``` -### delay - 延迟 Observable 发出数据的时间 +对 `Observable` 发出的值进行累加 + +### delay ```javascript -const obs = of('Hello').pipe( - delay(2000) -); +const obs = of('Hello').pipe(delay(2000)); obs.subscribe(console.log); // 输出: 'Hello' (延迟2秒) ``` -## 调度器 +延迟 `Observable` 发出数据的时间 + +调度器 +--- + +### 调度器说明 调度器(Scheduler)控制着 RxJS 操作的执行时机。常见的调度器有: -- `asyncScheduler`:异步执行任务。 -- `queueScheduler`:按队列顺序执行任务。 -- `animationFrameScheduler`:在浏览器的下一次重绘前执行任务。 +- `asyncScheduler`:异步执行任务 +- `queueScheduler`:按队列顺序执行任务 +- `animationFrameScheduler`:在浏览器的下一次重绘前执行任务 ### 示例 + ```javascript -const obs = of(1, 2, 3).pipe( - observeOn(asyncScheduler) -); +const obs = of(1, 2, 3).pipe(observeOn(asyncScheduler)); console.log('Before subscribe'); obs.subscribe(console.log); From 85d74eb81af9d453bd5c4fc0a1d276ae95cdc393 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Jun 2024 05:54:12 +0000 Subject: [PATCH 8/9] doc: update CONTRIBUTING.md. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d36abc1..9b027607 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -337,11 +337,11 @@ jobs: Steve Hartwell 南宫乘风 砹小翼 +h7ml Alex LufsX baoer expoli -h7ml k23223 二丫讲梵 undefined From 60fae2b928354c0b4b7b6bfc1d8f3bf8a2dc962d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Jun 2024 05:54:13 +0000 Subject: [PATCH 9/9] doc: update README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c1dda88..3b8d61da 100644 --- a/README.md +++ b/README.md @@ -286,11 +286,11 @@ Quick Reference Steve Hartwell 南宫乘风 砹小翼 +h7ml Alex LufsX baoer expoli -h7ml k23223 二丫讲梵 undefined