在 es6 中,创建一个带有回调的事件监听器到一个可迭代对象中

Posted

技术标签:

【中文标题】在 es6 中,创建一个带有回调的事件监听器到一个可迭代对象中【英文标题】:in es6, make an event listener with a callback into an iterable 【发布时间】:2015-06-09 21:38:33 【问题描述】:

我的 websocket 类 Wws 使用 onmessage 侦听所有传入消息。

对于使用 Wws(我的 websocket 模块)的程序,我希望它们能够通过 iterables“收听”。

例如,

// 监听新的博客消息 让 itr = ws.listen('blog', 'new'); // 显示我们收到的每个新博客 而(真) 让博客 = itr.next().value; 显示博客(博客);

任何数量的iterables 都可能挂在事件监听器上。

您将如何在ws 模块中编写generator

ws = 函数() conn = new Websocket(...); // 可以有传递消息的全局 `onmessage` conn.onmessage = function(msg) // 可以查看监听器并知道有迭代器 // 但是如何与他们交谈? 听众 = 新地图(); // 监听传入消息的生成器 监听器=函数*(服务,动作) // 可以将此 service.action 添加到侦听器,但是什么? // 这个人会创建自己的 `onmessage` 吗? // 如果是这样,他如何将 `yield` 传递给外部函数?

如何将带有callbacklistener 转换为iterator

【问题讨论】:

for… of 被阻止。只要您处于该循环中,它就会阻止您的服务器执行任何其他操作,包括接受新请求。你不想那样做。 @Touffy - 谢谢 - 不知道。改为then() 【参考方案1】:

您可以通过以下示例类完成此操作:

// A class that wraps a `WebSocket` to allow you to `await` on messages.
// Useful for blocking until a message is received, and continuing to listen
// afterward.
export class WebSocketMessageGenerator 
    private receivedMessages: Data[] = [];
    private wait: Promise<void>;
    private waitResolve?: () => void;
    private generator: AsyncGenerator<Data | undefined, void>;
    private closed = false;
    constructor(private readonly client: WebSocket) 
        this.generator = this.messages();
        this.wait = new Promise<void>((resolve) => 
            this.waitResolve = resolve;
        );

        this.client.on("message", (data: Data) => 
            this.receivedMessages.push(data);
            if(!this.waitResolve) 
                throw new Error("waitResolve is undefined");
            
            this.waitResolve();
            this.wait = new Promise<void>((resolve) => 
                this.waitResolve = resolve;
            );
        );

        this.client.on("close", () => 
            this.closed = true;
        );
    

    public async * messages() 
        while (!this.closed) 
            if (this.receivedMessages.length > 0) 
                yield this.receivedMessages.shift();
                continue;
            
            await this.wait;
        
    

    public async nextMessage<T>(): Promise<T> 
        const message = await this.generator.next();
        if (message.done) 
            throw new Error("No more messages");
        
        if (!message.value) 
            throw new Error("No message");
        
        return JSON.parse(message.value.toString());
    

这样调用:

const generator = new WebSocketMessageGenerator(new Websocket("url"));
const data = await generator.nextMessage();

【讨论】:

以上是关于在 es6 中,创建一个带有回调的事件监听器到一个可迭代对象中的主要内容,如果未能解决你的问题,请参考以下文章

如何使用ES6类添加事件侦听器并在画布中移动对象?

安卓点击事件回调机制的思考

ES6中的Promise

ES6

使用具有多个模块的模块模式,一个模块中的事件监听器如何使用来自另一个模块的回调?

es6 添加事件监听