并发
Targo 的并发模型来自 Go,而不是 JavaScript 的 async runtime。
核心规则
- 不支持
async/await和Promise - 使用
go(() => { ... })启动 goroutine - 使用
chan<T>进行通信 - 使用
switch (chan.$select)进行 select 风格协调 - 使用
defer在函数返回时执行清理 - 显式设计数据流和错误流,不要假设存在 JavaScript 异步运行时模型
Goroutine
使用 go() 启动 goroutine:
typescript
const ch = new chan<string>(1);
go(() => {
const result = compute();
ch.$send(result);
});
const value = ch.$recv();Goroutine 不是 Promise 包装器。只有在并发确实带来价值时才使用。
Channel
Channel 是 goroutine 之间的主要通信机制。
typescript
// 无缓冲 channel
const ch = new chan<int>();
// 有缓冲 channel
const buffered = new chan<string>(10);
// 发送
ch.$send(42);
// 接收
const value = ch.$recv();
// 关闭
ch.$close();Select
使用 switch (chan.$select) 等待多个 channel 操作:
typescript
const dataCh = new chan<string>(1);
const doneCh = new chan<void>(1);
switch (chan.$select) {
case dataCh.$recv(): {
const msg = dataCh.$recv();
console.log(msg);
break;
}
case doneCh.$recv(): {
console.log("done");
break;
}
}Defer
defer 安排一个函数调用在外层函数返回时执行:
typescript
function processFile(path: string): error | null {
const [f, err] = os.Open(path);
if (err != null) {
return err;
}
defer(() => f.Close());
// ... 使用 f ...
return null;
}实践模式
| 需求 | 优先选择 |
|---|---|
| 后台并发工作 | goroutine + channel |
| 等待多个通信路径 | switch (chan.$select) |
| 超时风格协调 | Go 风格 time + channel 流 |
| 函数退出时清理 | defer |
常见错误
- 把 goroutine 当成 Promise 包装器
- 只设计成功 channel,忘记失败路径
- 发送方完成后不关闭 channel
- 试图一对一翻译
Promise.all、race或await - 忘记
defer在函数返回时执行,而不是在块退出时