为事件处理程序编写中间件

时间:2018-04-29 11:19:03

标签: javascript node.js typescript

使用案例

我必须处理几个需要“可用客户端”的事件。因此,在每个事件处理程序中,我首先必须尝试获取可用的客户端。如果没有可用的客户端,我将回复“服务不可用”消息。现在我已经实现了这样的要求:

public constructor(consumer: RpcConsumer) {
  consumer.on('requestA', this.onRequestA);
}

private onRequestA = async (msg: RpcConsumerMessage) {
    const client: RequestClient = this.getClient(msg);
    if (client == null) {
      return;
    }

   msg.reply(await client.getResponseA());
}

private getClient(msg: RpcConsumerMessage): RequestClient {
    const client: RequestClient= this.clientManager.getClient();
    if (client == null) {
      const err: Error = new Error('Currently there is no client available to process this request');
      msg.reply(undefined, MessageStatus.ServiceUnavailable, err);

      return;
    }

    return client;
}

问题:

我不想一次又一次地检查所有事件处理程序中的可用客户端。相反,我认为中间件完全适合这个用例。它将检查可用的客户端并传递客户端实例(如果有)。如果没有可用的客户端,它将回复错误消息。

问题:

我如何为这种情况编写这样的中间件?

2 个答案:

答案 0 :(得分:2)

为此构建一个curried方法:

@Override
public View getView(final int position, View convertView, ViewGroup viewGroup) {
    if (convertView == null) {
        convertView = View.inflate(mContext, R.layout.product_item_intro, null);
        iv_intro_img = convertView.findViewById(R.id.iv_intro_img);
    }
    String imgurl = datas.get(position); //+ "_500x500.jpg";
    RequestOptions myOptions = new RequestOptions()
        .fitCenter();

    Glide.with(mContext).load(imgurl).apply(myOptions).into(iv_intro_img);

    iv_intro_img.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int itemtHeight = iv_intro_img.getHeight();
            int itemtHeight2= iv_intro_img.getMeasuredHeight();
            Log.e("itemimageview" + position, "height" + itemtHeight + "," + itemtHeight2);
            iv_intro_img.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });
    return convertView;
}

所以你可以用它作为:

 private withClient(cb: (client: RequestClient) => string | Promise<string>) {
  return function(msg: RpcConsumerMessage) {
    const client: RequestClient= this.clientManager.getClient();
    if (client == null) {
      const err: Error = new Error('Currently there is no client available to process this request');
      msg.reply(undefined, MessageStatus.ServiceUnavailable, err);

      return;
    }

    msq.reply(await cb(client));
   };
 }

答案 1 :(得分:0)

如果我理解正确,我认为你实际上并不需要中间件,尽管你可能选择走那条路。

您可以拥有一个负责寻找客户的模块,如果可用,则可以提供服务。这看起来像这样:

const _client;

module.exports = {
    getClient
}

getClient(){
     return _client;
}

function setClient(){
    //Your logic to find an available client
    //run this whenever a client disconnects (if there is an event for that) or until you are connected to a client
    _clent = client; //When you find that client set it to `_client`. You will return this everytime someone calls getClient.
}

这里的优点是,一旦找到客户端,该模块将为同一客户端提供服务,直到您断开连接。诀窍就是确保在断开连接时始终尝试连接到客户端 - 即使没有请求也是如此。我希望这是有道理的。