简体   繁体   English

尝试解决使用 setTimeOut、setInterval 和回调发送和接收消息的练习问题

[英]Trying to solve a practice problem sending and receiving messages with setTimeOut, setInterval, and callbacks

I'm working on a practice problem using setTimeOut and callbacks for the first time.我正在第一次使用 setTimeOut 和回调来解决练习问题。 This is the situation:情况是这样的:

You receive a JavaScript object 'recordMap' of the following您收到以下 JavaScript 对象“recordMap”

            type: { [recordName: string]: Client }

Client is an interface allowing to a) send a text message, b) receive a text message by registering a callback function.客户端是一个接口,允许 a) 发送文本消息,b) 通过注册回调函数接收文本消息。

    interface Client {

    sendMessage: (message: string) => void;

    //to send messages to the Client

    onMessage: (callback: (message: string) => void) => 
              void; // a callback for receiving messages from the 
              Client

    }

Public method 'initialize' will initialize the tracking of active Clients.公共方法“初始化”将初始化对活动客户端的跟踪。

The goal is to make sure that no records in 'recordMap' are kept for inactive Clients.目标是确保“recordMap”中没有为非活动客户端保留任何记录。

//to register Send a 'ping' message to all Clients every 10 seconds. //注册每10秒向所有客户端发送'ping'消息。 Register a callback function to receive messages from Clients.注册一个回调函数来接收来自客户端的消息。

Sending and receiving messages is an asynchronous form of communication - give Clients 3 seconds to reply to your message.发送和接收消息是一种异步通信形式 - 给客户端 3 秒钟回复您的消息。

For every Client who hasn't replied with a 'pong' message, remove his record from 'recordMap'.对于每个没有回复“pong”消息的客户,从“recordMap”中删除他的记录。

           type RecordMap = { [recordName: string]: Client };

           class RecordTracker {

             constructor (private recordMap: RecordMap) {}

             public initialize (): void {

             ...?

             }

             public getRecordMap (): RecordMap {

               return { ...this.recordMap };
             }
           }

I feel like I need to use setInterval for a message every 10 seconds and setTimeOut to send and receive the message, but not sure where to go from there.我觉得我需要每 10 秒使用一次消息 setInterval 和 setTimeOut 来发送和接收消息,但不确定从那里去哪里。

I'm not really sure where to go with this one.我真的不知道用这个去哪里。 Do I need to create some dummy clients to call?我需要创建一些虚拟客户端来调用吗? This is what I have so far:这是我到目前为止:

```
interface Client {
  sendMessage: (message: string) => void;
  onMessage: (callback: (message: string) => void) => void;
}

type RecordMap = { [recordName: string]: Client };

class RecordTracker {
  constructor (private recordMap: RecordMap) {}
  public initialize (): void {
    setInterval(() => {
      const sendMessage = (message) => {
        //????
      }
    }, 10000)
  }
  public getRecordMap (): RecordMap {
    return { ...this.recordMap };
  }
}```

I would start by designing a function that accepts a Client and checks to see whether it's still active.我将首先设计一个接受客户端并检查它是否仍然处于活动状态的函数。 Once you've ironed out that part, it should be straightforward to wire it into some kind of regular testing regime.一旦你解决了那个部分,就可以直接将它连接到某种常规测试制度中。

Since sending a message is asynchronous, our function is async.由于发送消息是异步的,我们的函数是异步的。 And, since we want to forcibly resolve it, we'll explicitly create a Promise so that we can resolve it after a timeout.并且,由于我们想强制解析它,我们将显式创建一个 Promise 以便我们可以在超时后解析它。

Here's a sketch of what I have in mind:这是我想到的草图:

async function getIsClientActive( client, timeoutMs ) {
    return new Promise(resolve => {
        // set up the timeout
        setTimeout(() => resolve(false), timeoutMs)

        // set up handler to listen for pong
        const pongReceiver = ( msg ) => {
            if(msg === 'pong') resolve(true)
        }

        client.onMessage = pongReceiver

        // send the ping
        client.sendMessage('ping')
    })
}

One big caveat: my getIsClientActive assumes it's safe to hijack each client's onMessage handler.一个重要的警告:我的getIsClientActive假设劫持每个客户端的onMessage处理程序是安全的。 If that's not safe, you could either temporarily store the current handler in RAM during the ping operation (simpler), or set up an EventEmitter for each Client that fires "message" events and which the ping operation could temporarily subscribe to (more robust)如果这不安全,您可以在 ping 操作期间将当前处理程序临时存储在 RAM 中(更简单),或者为每个触发“消息”事件的客户端设置一个 EventEmitter 并且 ping 操作可以临时订阅(更健壮)


One thing I want to stress: it will make your job easier if this client-probing operation can remain ignorant of the data structures your program uses to track all known clients.我想强调的一件事是:如果这个客户端探测操作可以不知道你的程序用来跟踪所有已知客户端的数据结构,那么它会让你的工作更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM