mirror of
https://github.com/jaywcjlove/reference.git
synced 2025-06-19 13:41:21 +08:00
Merge branch 'jaywcjlove:main' into feat/threejs
This commit is contained in:
450
docs/erlang.md
Normal file
450
docs/erlang.md
Normal file
@ -0,0 +1,450 @@
|
||||
Erlang 备忘清单
|
||||
===
|
||||
|
||||
[Erlang](https://www.erlang.org/) 是一种用于构建并发、分布式和容错系统的编程语言。以下是一些常用的命令和操作。
|
||||
|
||||
入门
|
||||
---
|
||||
|
||||
### 启动 Erlang Shell
|
||||
|
||||
```shell
|
||||
erl
|
||||
```
|
||||
|
||||
### 编译代码
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```shell
|
||||
# 在 Erlang Shell 中编译
|
||||
c(module).
|
||||
# 在命令行中编译
|
||||
erlc module.erl
|
||||
```
|
||||
|
||||
### 运行代码
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
```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
|
||||
% 单行注释
|
||||
% 这是一个注释
|
||||
```
|
||||
|
||||
### 变量
|
||||
|
||||
```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)
|
||||
---
|
||||
|
||||
### 列表操作
|
||||
|
||||
```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
|
||||
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.
|
||||
```
|
||||
|
||||
并发编程
|
||||
---
|
||||
|
||||
### 创建进程
|
||||
|
||||
```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`
|
||||
|
||||
### 错误处理
|
||||
|
||||
```erlang
|
||||
try Expression of
|
||||
Pattern -> Result
|
||||
catch
|
||||
Type:Reason -> ErrorHandlingExpression
|
||||
end.
|
||||
```
|
||||
|
||||
分布式编程
|
||||
---
|
||||
|
||||
### 启动分布式节点
|
||||
|
||||
```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)
|
419
docs/rxjs.md
Normal file
419
docs/rxjs.md
Normal file
@ -0,0 +1,419 @@
|
||||
RxJS 备忘清单
|
||||
===
|
||||
|
||||
[RxJS](https://rxjs.dev/)(Reactive Extensions for JavaScript)是一个强大的库,用于处理异步事件和数据流。以下是 RxJS 的一些关键概念、操作符和方法的总结。
|
||||
|
||||
## 入门
|
||||
|
||||
### 安装 RxJS
|
||||
|
||||
```bash
|
||||
npm install rxjs
|
||||
```
|
||||
|
||||
### 清晰
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
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` 类似。它接受一个暴露给回调函数的值。回调的返回值将成为下次回调运行时公开的下一个值。
|
||||
|
||||
### 流
|
||||
<!--rehype:wrap-class=row-span-2-->
|
||||
|
||||
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 和操作符
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```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
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 2 3
|
||||
```
|
||||
|
||||
创建一个立即发送指定值并完成的 Observable
|
||||
|
||||
### from
|
||||
|
||||
```javascript
|
||||
const obs = from([1, 2, 3]);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 2 3
|
||||
```
|
||||
|
||||
从 Promise、数组、可迭代对象创建 Observable
|
||||
|
||||
### interval
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000);
|
||||
obs.subscribe(console.log);
|
||||
// 每秒输出一次递增的数字
|
||||
```
|
||||
|
||||
创建一个定时发送递增整数的 Observable
|
||||
|
||||
### fromEvent
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
const button = document.querySelector('button');
|
||||
const obs = fromEvent(button, 'click');
|
||||
obs.subscribe(event => {
|
||||
console.log('Button clicked!', event)
|
||||
});
|
||||
```
|
||||
|
||||
从 DOM 事件创建 Observable
|
||||
|
||||
## 操作符
|
||||
|
||||
### map
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
map(x => x * 2)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 2 4 6
|
||||
```
|
||||
|
||||
对 Observable 发出的每个值应用一个函数
|
||||
|
||||
### filter
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
filter(x => x % 2 === 0)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 2
|
||||
```
|
||||
|
||||
过滤 Observable 发出的值
|
||||
|
||||
### switchMap
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000).pipe(
|
||||
switchMap(() => of('Hello'))
|
||||
);
|
||||
|
||||
obs.subscribe(console.log);
|
||||
// 每秒输出一次 "Hello"
|
||||
```
|
||||
|
||||
将 Observable 每个值映射成 Observable 并订阅,前一个订阅将被取消
|
||||
|
||||
### mergeMap
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000).pipe(
|
||||
mergeMap(() => of('Hello'))
|
||||
);
|
||||
|
||||
obs.subscribe(console.log);
|
||||
// 每秒输出一次 "Hello"
|
||||
```
|
||||
|
||||
类似 switchMap,但允许多个内部 Observable 并发执行
|
||||
|
||||
### catchError
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
map(x => {
|
||||
if (x === 2) throw 'Error!';
|
||||
return x;
|
||||
}),
|
||||
catchError(err => of('发现一个错误:'+err))
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 发现一个错误:Error!
|
||||
```
|
||||
|
||||
捕获 Observable 链中的错误
|
||||
|
||||
### debounceTime
|
||||
|
||||
```javascript
|
||||
const obs = fromEvent(document,'mousemove')
|
||||
.pipe(debounceTime(300));
|
||||
|
||||
obs.subscribe(event => {
|
||||
console.log('Mouse moved!', event)
|
||||
});
|
||||
```
|
||||
|
||||
延迟处理,直到源 Observable 停止发出数据一定时间
|
||||
|
||||
### distinctUntilChanged
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 1, 2, 2, 3, 3).pipe(
|
||||
distinctUntilChanged()
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 2 3
|
||||
```
|
||||
|
||||
忽略连续重复的值
|
||||
|
||||
### take
|
||||
|
||||
```javascript
|
||||
const obs = interval(1000).pipe(
|
||||
take(3)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 0 1 2
|
||||
```
|
||||
|
||||
只发出前 n 个值
|
||||
|
||||
## 组合操作符
|
||||
|
||||
### combineLatest
|
||||
|
||||
```javascript
|
||||
const obs1 = interval(1000);
|
||||
const obs2 = of('A', 'B', 'C');
|
||||
const combined = combineLatest(
|
||||
[obs1, obs2]
|
||||
);
|
||||
|
||||
combined.subscribe(console.log);
|
||||
// 每秒输出一次两个 observables 的最新值
|
||||
```
|
||||
|
||||
当两个 Observable 都发出新的值时,发出它们的组合
|
||||
|
||||
### concat
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
按顺序连接多个 Observable
|
||||
|
||||
### merge
|
||||
|
||||
```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" 开头的递增数字
|
||||
```
|
||||
|
||||
将多个 Observable 合并为一个
|
||||
|
||||
### forkJoin
|
||||
|
||||
```javascript
|
||||
const obs1 = of(1, 2, 3);
|
||||
const obs2 = of('A', 'B', 'C');
|
||||
const combined = forkJoin([obs1, obs2]);
|
||||
combined.subscribe(console.log);
|
||||
// 输出: [3, 'C']
|
||||
```
|
||||
|
||||
等待所有 Observable 完成,然后发出它们的最后一个值的数组
|
||||
|
||||
## 错误处理
|
||||
|
||||
### retryWhen
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
const obs = throwError('出了些问题!')
|
||||
.pipe(
|
||||
retryWhen(errors =>
|
||||
errors.pipe(delayWhen(() => interval(1000)))
|
||||
)
|
||||
);
|
||||
obs.subscribe(console.log, console.error);
|
||||
// 输出: 出了些问题! (每秒重试一次)
|
||||
```
|
||||
|
||||
在 Observable 发出错误时重试
|
||||
|
||||
## 实用操作符
|
||||
|
||||
### 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
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
startWith(0)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 0 1 2 3
|
||||
```
|
||||
|
||||
在 `Observable` 序列前添加值
|
||||
|
||||
### scan
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(
|
||||
scan((acc, value) => acc + value, 0)
|
||||
);
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 1 3 6
|
||||
```
|
||||
|
||||
对 `Observable` 发出的每个值应用累加器函数
|
||||
|
||||
### reduce
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```javascript
|
||||
const obs = of(1, 2, 3).pipe(reduce((acc, value) => acc + value, 0));
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 6
|
||||
```
|
||||
|
||||
对 `Observable` 发出的值进行累加
|
||||
|
||||
### delay
|
||||
|
||||
```javascript
|
||||
const obs = of('Hello').pipe(delay(2000));
|
||||
obs.subscribe(console.log);
|
||||
// 输出: 'Hello' (延迟2秒)
|
||||
```
|
||||
|
||||
延迟 `Observable` 发出数据的时间
|
||||
|
||||
调度器
|
||||
---
|
||||
|
||||
### 调度器说明
|
||||
|
||||
调度器(Scheduler)控制着 RxJS 操作的执行时机。常见的调度器有:
|
||||
|
||||
- `asyncScheduler`:异步执行任务
|
||||
- `queueScheduler`:按队列顺序执行任务
|
||||
- `animationFrameScheduler`:在浏览器的下一次重绘前执行任务
|
||||
|
||||
### 示例
|
||||
<!--rehype:wrap-class=col-span-2-->
|
||||
|
||||
```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)
|
Reference in New Issue
Block a user