在 TypeScript 中,方法前面加 * 表示这是一个 生成器函数(Generator Function) 。
基本语法
typescript
function* sendMessageStream() {
// 函数体
yield "消息1";
yield "消息2";
yield "消息3";
}
生成器函数的特点
1. 使用 yield 关键字
typescript
function* messageGenerator() {
yield "Hello";
yield "World";
yield "!";
}
const generator = messageGenerator();
console.log(generator.next()); // { value: "Hello", done: false }
console.log(generator.next()); // { value: "World", done: false }
console.log(generator.next()); // { value: "!", done: false }
console.log(generator.next()); // { value: undefined, done: true }
2. 可暂停和恢复执行
typescript
function* countGenerator() {
let count = 0;
while (count < 3) {
yield count++;
}
}
const counter = countGenerator();
console.log(counter.next().value); // 0
console.log(counter.next().value); // 1
console.log(counter.next().value); // 2
console.log(counter.next().value); // undefined
实际应用场景
1. 消息流处理(如 sendMessageStream)
typescript
function* sendMessageStream(messages: string[]) {
for (const message of messages) {
// 可以在这里添加处理逻辑
const processedMessage = `[${new Date().toISOString()}] ${message}`;
yield processedMessage;
// 模拟一些延迟或条件
if (message === "stop") {
return; // 结束生成器
}
}
}
// 使用示例
const messages = ["消息1", "消息2", "stop", "消息3"];
const stream = sendMessageStream(messages);
let result = stream.next();
while (!result.done) {
console.log(result.value);
result = stream.next();
}
2. 无限序列
typescript
function* idGenerator() {
let id = 1;
while (true) {
yield id++;
}
}
const idGen = idGenerator();
console.log(idGen.next().value); // 1
console.log(idGen.next().value); // 2
console.log(idGen.next().value); // 3
// 可以无限继续...
3. 状态机
typescript
function* trafficLight() {
while (true) {
yield "red";
yield "yellow";
yield "green";
}
}
const light = trafficLight();
console.log(light.next().value); // "red"
console.log(light.next().value); // "yellow"
console.log(light.next().value); // "green"
console.log(light.next().value); // "red"
与异步生成器的区别
普通生成器
typescript
function* syncGenerator() {
yield 1;
yield 2;
yield 3;
}
异步生成器(ES2018+)
typescript
async function* asyncSendMessageStream() {
yield await fetchMessage1();
yield await fetchMessage2();
yield await fetchMessage3();
}
// 使用 for await...of
async function processMessages() {
for await (const message of asyncSendMessageStream()) {
console.log(message);
}
}
在类中的使用
typescript
class MessageService {
private messages: string[] = [];
*sendMessageStream(): Generator<string> {
for (const message of this.messages) {
yield `Processed: ${message}`;
}
}
// 异步版本
async *sendAsyncMessageStream(): AsyncGenerator<string> {
for (const message of this.messages) {
// 模拟异步操作
const processed = await this.processMessageAsync(message);
yield processed;
}
}
private async processMessageAsync(message: string): Promise<string> {
return `Async: ${message}`;
}
}
实际用例:分页数据流
typescript
function* paginatedDataStream(pageSize: number = 10) {
let page = 0;
let hasMore = true;
while (hasMore) {
// 模拟 API 调用获取分页数据
const data = fetchPageData(page, pageSize);
if (data.length === 0) {
hasMore = false;
return; // 没有更多数据
}
yield data;
page++;
// 可以添加条件来停止
if (page > 100) { // 安全限制
hasMore = false;
}
}
}
// 模拟分页数据获取
function fetchPageData(page: number, pageSize: number): any[] {
// 返回模拟数据
return Array.from({ length: pageSize }, (_, i) => ({
id: page * pageSize + i,
content: `Item ${page * pageSize + i}`
}));
}
总结
方法前加 * 表示生成器函数:
- 可暂停执行 :使用
yield暂停函数执行并返回值 - 保持状态:函数调用之间的状态会被保留
- 惰性求值:值在需要时才生成
- 迭代协议 :遵循迭代器协议,可与
for...of循环配合使用
对于 sendMessageStream 这样的方法,很可能是用于:
- 逐步发送消息
- 处理消息流
- 实现某种状态机或序列生成
- 分批次处理数据