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

  • 逐步发送消息
  • 处理消息流
  • 实现某种状态机或序列生成
  • 分批次处理数据
相关推荐
a1117762 小时前
医院挂号预约系统(开源 Fastapi+vue2)
前端·vue.js·python·html5·fastapi
0思必得02 小时前
[Web自动化] Selenium处理iframe和frame
前端·爬虫·python·selenium·自动化·web自动化
行走的陀螺仪4 小时前
uni-app + Vue3编辑页/新增页面给列表页传参
前端·vue.js·uni-app
We་ct5 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
2301_812731416 小时前
CSS3笔记
前端·笔记·css3
ziblog6 小时前
CSS3白云飘动动画特效
前端·css·css3
越努力越幸运5086 小时前
CSS3学习之网格布局grid
前端·学习·css3
半斤鸡胗6 小时前
css3基础
前端·css
ziblog6 小时前
CSS3创意精美页面过渡动画效果
前端·css·css3
akangznl6 小时前
第四章 初识css3
前端·css·css3·html5