首页 > 其他分享 >消灭事件回调,让其直接变成线性同步的代码风格

消灭事件回调,让其直接变成线性同步的代码风格

时间:2024-06-16 20:32:57浏览次数:24  
标签:同步 代码 Javascript send 线性 new message public waitMessageSource

在 C# 和 Javascript 语言下,讨论如何封装事件返回的回调

问题场景

比如有一个库中,有一个 send 方法,用于发送命令,然后需要等待返回值,但 send 方法本身没有返回值,而是通过另外的事件来获取返回值。
伪代码如下:

// 通过事件回调来接收命令执行结果
foo.onDataReceive = (result) => { // receive result }
// 发送命令
foo.send("command")

这在使用上其实不是很方便,而且理解起来不直观,期望可以有如下的封装

var result = await myFoo.Send("command")

下面介绍在 C# 和 Javascript 中如何处理,在 C# 中使用的是 TaskCompletionSource 这个 API,Javascript 中使用的就是 Promise

尤其是 C# 中的这个 API,其实很简单,但是如果不知道,还真一时半会想不到特别优雅的方案。
在 Javascript 中,Promise 的提出,作用之一就是为了解决回调地狱,所以这个方案在 Javascript 显得就很自然。

csharp 版本

MessageSender 是原始 API, MyMessageSender 是封装。这里就可以直接使用 SendAsync 进行异步调用拿到结果,或者捕获异常。

class MyMessageSender
{
    private TaskCompletionSource<string> _waitMessageSource = new();

    private readonly MessageSender _messageSender;

    public MyMessageSender()
    {
        _messageSender = new MessageSender();
        _messageSender.MessageReceived += (sender, args) =>
        {
            if (args.ErrorCode == 0)
            {
                // 成功收到数据,则设置数据
                _waitMessageSource.TrySetResult(args.Response);
            }
            else
            {
                // 没有成功,则抛出异常
                _waitMessageSource.TrySetException(new MessageReceivedException(args.ErrorCode, args.Response));
            }
        };
    }

    /// <summary>
    /// 发送请求数据,并获取响应
    /// </summary>
    /// <param name="request"></param>
    /// <returns>响应数据</returns>
    /// <exception cref="MessageReceivedException">数据接收出现错误</exception>
    public async Task<string> SendAsync(string request)
    {
        _waitMessageSource = new();
        _messageSender.Send(request);
        return await _waitMessageSource.Task;
    }

}

class MessageSender
{
    public event EventHandler<MessageReceivedEventArgs> MessageReceived;

    public void Send(string message)
    {

    }
}

class MessageReceivedEventArgs : EventArgs
{
    public int ErrorCode { get; set; }

    public string Response { get; set; } = "";
}

class MessageReceivedException(int code, string? message) : ApplicationException(message)
{
    public int ErrorCode { get; set; } = code;
}

javascript 版本

js 中直接使用 Promise 来包装回调,这个是很自然的操作

sender = {
  send(request, callback) {},
};

mySender = {
  send(request) {
    return new Promise((resolve, reject) => {
      let callback = (response) => {
        if (response.code == 0) {
          resolve(response.message);
        } else {
          reject({
            errorCode: response.code,
            message: response.message,
          });
        }
      };
      sender.send(request, callback);
    });
  },
};

好处

当然是让代码逻辑更清晰,将回调写法,变成线性执行,对于复杂业务来说,能够很好让代码更可读和可理解

标签:同步,代码,Javascript,send,线性,new,message,public,waitMessageSource
From: https://www.cnblogs.com/jasongrass/p/18220886

相关文章

  • KAN神经网络 | KAN函数拟合附代码
    首先,让我们快速概述一下KAN及其实现的理论:柯尔莫哥洛夫-阿诺德表示定理:我们跳过繁琐的公式和定义,只用一个简单的解释。KART指出,任何具有多个输入的连续函数都可以通过组合单个输入的简单函数(如正弦或平方)并将它们相加来创建。例如,多元函数f(x,y)=x*y。这可以写成:((......
  • 如何从0到1实现一个go语言代码项目
    创建一个Go语言项目是一个逐步的过程,这里我将为你提供一个简单的项目示例,包括一些基础步骤来帮助你从0开始实现一个Go语言项目。步骤1:安装Go语言环境首先,你需要在你的计算机上安装Go语言环境。你可以从[Go官网](https://golang.org/dl/)下载适合你操作系统的安装包。......
  • 08_线性回归详解
    线性回归详解1、包导入与数据创建importnumpyasnpimportmatplotlibimportmatplotlib.pyplotasplt#绘图全局参数设置config={"font.family":'TimesNewRoman',"font.size":14,"font.serif":'Simsun',}matplo......
  • 帮猪猪修修改的代码2016年的代码记录
    这是一个图片轮播的代码,但是它们的是css动画,当时代码运行不了,我花了二天才修改,现在记录一下,凭回忆用。<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>网易科技</title><metaname="viewport"content="width=de......
  • 08梦断代码阅读笔记之三
     自身对于何为软件,何为代码仅有一些肤浅的认识,半学期下来,编程能力也有了较大的提高。但是其中的痛苦和艰辛,也很值得自己去慢慢的回味。书中描述一群人们怀抱着改变世界的理想上路了,却在追寻时发现,那些近在眼前的理想之峰,变得那么的遥不可及;每当翻过一座横亘在面前的山峰时,总以为......
  • 【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II) C语言代码实现[思路+代码]
    【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript-CSDN博客JS、Java、C、python、C++代码实现:【华为OD】D卷真题100分:阿里巴巴找黄金宝箱(II)JavaScript代码实现[思......
  • 【华为OD】D卷真题200分:数字游戏 python代码实现[思路+代码]
    【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript-CSDN博客JS、Java、C、python、C++代码实现:【华为OD】D卷真题200分:数字游戏JavaScript代码实现[思路+代码]-CSDN......
  • 【华为OD】D卷真题100分: 生日礼物 C++代码实现
    【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript【华为OD】2024年C、D卷真题集:最新的真题集题库C/C++/Java/python/JavaScript-CSDN博客C、java、python、JS、C++代码实现:【华为OD】D卷真题100分:生日礼物C语言代码实现-CSDN博客【华为OD】D......
  • 循环神经网络(RNN)入门指南及代码示例
    简介循环神经网络(RecurrentNeuralNetwork,RNN)是一种擅长处理序列数据的神经网络结构。与传统的前馈神经网络不同,RNN拥有循环连接,可以保留以前的信息,从而在处理时间序列数据、自然语言处理等任务中表现出色。在这篇文章中,我们将详细介绍RNN的基本概念及其变体LSTM和GRU,并通过......
  • 【代码+详解】算法题 : 骨头收集者
    ❗❗❗必看:下列题我全部都使用Java语言写的,并且均可以提交成功,获得Accepted结果的.如果代码和详解看了之后,对答案有任何疑问,都可以在评论区提出来,我都会一个一个回答.❗❗❗感谢大家的支持,如果喜欢我的博客,关注点赞收藏评论一波,非常感谢!!!文章目录......