typescript 方法前面加* 是什么意思

在 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 这样的方法,很可能是用于:

  • 逐步发送消息
  • 处理消息流
  • 实现某种状态机或序列生成
  • 分批次处理数据
相关推荐
deli0079 小时前
Skill 怎么写才被 Agent 命中?18 条规则做成 SKILL.md 校验器,规范样例 92 分
前端
Hum8le9 小时前
CTF题目《easy_web》(安洵杯 2019 变种 Web)
前端·安全·web安全
coding漫漫长路9 小时前
二值化后还剩1212个黑点,OCR却认成了乱码
前端
不可能片场9 小时前
AI视频口型对齐 用音频驱动说话镜头
前端·electron
Lank_M9 小时前
OCR一个字没认错,倾斜2.5°却把行序排乱了
前端
daols889 小时前
vue 表格组件 vxe-table 实现自定义多行编辑功能
前端·javascript·vue.js·vxe-table
不要试图纠正别人9 小时前
别让大模型算钱:我把优惠券组合优化写成了确定性算法
前端
IT_Octopus9 小时前
【零基础入门 LLM 开发 · Day 11】:ChatOpenAI vs init_chat_model——一行换供应商
java·前端·javascript
柚yuzumi10 小时前
React 19 Hooks 入门:函数组件的四大法宝 (useState / useEffect / useRef / useContext)
前端·javascript·架构
deli00710 小时前
撒下 200 个种子点,平面为什么自己长成蜂窝?Voronoi 图实验室
前端