第2章 逻辑分页、AutoFac注入、工作单元与仓储

1 CoreCms.Net.Model.ViewModels.Basics.IPageList<T>

namespace CoreCms.Net.Model.ViewModels.Basics

{

    ///<typeparam name="T">泛型类型实例(1个指定实体的类型实例)</typeparam>

    /// <summary>

    /// 【逻辑分页列表--接口】

    /// <remarks>

    /// 摘要:

    ///     通过继承该接口的具体实现类中的属性成员实例,逻辑的从数据源中加载指定1页中的数据,存储到1逻辑页中,从而尽量少的从指定表加载数据,从而尽量降低内存的消耗。

    /// 说明:

    ///     逻辑分页交互操作对象是当前程序与数据库的指定表。

    /// </remarks>

    /// </summary>

    public interface IPageList<T> : IList<T>

    {

        #region 属性

        /// <summary>

        /// 【当前页】

        /// <remarks>

        /// 摘要:

        ///     获取/设置当前页,当前逻辑(内存)页面的整型索引值,从“0”开始计算。

        /// </remarks>

        /// </summary>

        int PageIndex { get; }

        /// <summary>

        /// 【页面大小】

        /// <remarks>

        /// 摘要:

        ///     获取/设置页面大小,即1逻辑(内存)页面最多所存储的实例项的整型个数值。

        /// </remarks>

        /// </summary>

        int PageSize { get; }

        /// <summary>

        /// 【总计值】

        /// <remarks>

        /// 摘要:

        ///     获取/设置数据源实例项的整型总计值。

        /// </remarks>

        /// </summary>

        int TotalCount { get; }

        /// <summary>

        /// 【总页数】

        /// <remarks>

        /// 摘要:

        ///     获取/设置总页数,即数据源实例项,可以分为逻辑页数的总计值。

        /// </remarks>

        /// </summary>

        int TotalPages { get; }

        /// <summary>

        /// 【上1页?】

        /// <remarks>

        /// 摘要:

        ///     获取1个值false(没有)/true(),该值指示在逻辑(内存)分页操作中当前页是否有上1(1页之前没有上1)

        /// </remarks>

        /// </summary>

        bool HasPreviousPage { get; }

        /// <summary>

        /// 【下1页?】

        /// <remarks>

        /// 摘要:

        ///     获取1个值false(没有)/true(),该值指示在逻辑(内存)分页操作中当前页是否有下1(最后1页之后没有下1)

        /// </remarks>

        /// </summary>

        bool HasNextPage { get; }

        #endregion

    }

}

2 CoreCms.Net.Model.ViewModels.Basics.PageList<T>  

namespace CoreCms.Net.Model.ViewModels.Basics

{

    ///<typeparam name="T">泛型类型实例(1个指定实体的类型实例)</typeparam>

    /// <summary>

    /// 【逻辑分页列表--类】

    /// <remarks>

    /// 摘要:

    ///     通过该类及其属性成员实例,只逻辑的从数据源中加载指定1页中的数据,存储到1(逻辑)页中,从而尽量少的从指定表加载数据,从而尽量降低内存的消耗。

    /// 说明:

    ///     (逻辑)分页交互操作对象是当前程序与数据库的指定表。

    /// [Serializable]

    ///     序列化可以对象的状态信息转换成可以持久化或者可以传输形式的过程。一般是转为字节数据。而把字节数组还原成原来同等对象的过程成为反序列化。

    ///     这里特指把逻辑分页实体中的所有数据换成可以进行网络传输的形式。

    /// </remarks>

    /// </summary>

    [Serializable]

    public class PageList<T> : List<T>, IPageList<T>

    {

        #region 拷贝构造方法

        ///<typeparam name="T">泛型类型实例(1个指定实体的类型实例)</typeparam>

        /// <param name="source">“IQueryable”实例进行存储的1个指定类型的数据源(枚举数接口实例=长串型,包含:数组、列表、字典等)</param>

        /// <param name="pageIndex">分页操作中当前页的整型索引值。</param>

        /// <param name="pageSize">1逻辑(内存)页面最多所存储的实例项的整型个数值。</param>

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     通过拷贝构造方法为该类中的属性成员赋值实例化初始值,并获取1逻辑(内存)页面内的所有数据。

        /// </remarks>

        /// </summary>

        public PageList(IQueryable<T> source, int pageIndex, int pageSize)

        {

            var total = source.Count();

            TotalCount = total;

            TotalPages = total / pageSize;

            if (total % pageSize > 0)

                TotalPages++;

            PageSize = pageSize;

            PageIndex = pageIndex;

            AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());

        }

        /// <param name="source">以列表接口实例进行存储的1个指定类型的数据源(包含:数组、列表、字典等)</param>

        /// <param name="pageIndex">分页操作中当前页的整型索引值。</param>

        /// <param name="pageSize">1逻辑(内存)页面最多所存储的实例项的整型个数值。</param>

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     通过拷贝构造方法为该类中的属性成员赋值实例化初始值,并获取1逻辑(内存)页面内的所有数据。

        /// </remarks>

        /// </summary>

        public PageList(IList<T> source, int pageIndex, int pageSize)

        {

            TotalCount = source.Count();

            TotalPages = TotalCount / pageSize;

            if (TotalCount % pageSize > 0)

                TotalPages++;

            PageSize = pageSize;

            PageIndex = pageIndex;

            AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());

        }

        /// <param name="source">以列表接口实例进行存储的1个指定类型的数据源(包含:数组、列表、字典等)</param>

        /// <param name="pageIndex">分页操作中当前页的整型索引值。</param>

        /// <param name="pageSize">1逻辑(内存)页面最多所存储的实例项的整型个数值。</param>

        /// <param name="totalCount">数据源实例项的整型总计值。</param>

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     通过拷贝构造方法为该类中的属性成员赋值实例化初始值,并获取1逻辑(内存)页面内的所有数据。

        /// </remarks>

        /// </summary>

        public PageList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)

        {

            TotalCount = totalCount;

            TotalPages = TotalCount / pageSize;

            if (TotalCount % pageSize > 0)

                TotalPages++;

            PageSize = pageSize;

            PageIndex = pageIndex;

            AddRange(source);

        }

        #endregion

        #region 属性

        /// <summary>

        /// 【当前页】

        /// <remarks>

        /// 摘要:

        ///     获取/设置当前页,当前逻辑(内存)页面的整型索引值,从“0”开始计算。

        /// </remarks>

        /// </summary>

        public int PageIndex { get; }

        /// <summary>

        /// 【页面大小】

        /// <remarks>

        /// 摘要:

        ///     获取/设置页面大小,即1逻辑(内存)页面最多所存储的实例项的整型个数值。

        /// </remarks>

        /// </summary>

        public int PageSize { get; private set; }

        /// <summary>

        /// 【总计值】

        /// <remarks>

        /// 摘要:

        ///     获取/设置数据源实例项的整型总计值。

        /// </remarks>

        /// </summary>

        public int TotalCount { get; }

        /// <summary>

        /// 【总页数】

        /// <remarks>

        /// 摘要:

        ///     获取/设置总页数,即数据源实例项,可以分为逻辑页数的总计值。

        /// </remarks>

        /// </summary>

        public int TotalPages { get; }

        /// <summary>

        /// 【上1页?】

        /// <remarks>

        /// 摘要:

        ///     获取1个值false(没有)/true(),该值指示在逻辑(内存)分页操作中当前页是否有上1(1页之前没有上1)

        /// </remarks>

        /// </summary>

        public bool HasPreviousPage => PageIndex > 0;

        /// <summary>

        /// 【下1页?】

        /// <remarks>

        /// 摘要:

        ///     获取1个值false(没有)/true(),该值指示在逻辑(内存)分页操作中当前页是否有下1(最后1页之后没有下1)

        /// </remarks>

        /// </summary>

        public bool HasNextPage => PageIndex + 1 < TotalPages;

        #endregion

    }

}

3 CoreCms.Net.Core.AutoFac.AutofacModuleRegister  

using Autofac;

using System.Reflection;

namespace CoreCms.Net.Core.AutoFac

{

    /// <summary>

    /// Autofac模型注入--类】

    /// <remarks>

    /// 摘要:

    ///     通过该类中的方法成员把指定的程序集(*.dll)依赖注入到Autofac容器中。

    /// </remarks>

    /// </summary>

    public class AutofacModuleRegister : Autofac.Module

    {

        /// <param name="builder">Autofac依赖注入容器实例。</param>

        /// <summary>

        /// 【载入】

        /// <remarks>

        /// 摘要:

        ///     通过该方法把指定程序集中的所有实例依赖注入到Autofac容器中。

        /// </remarks>

        /// </summary>

        protected override void Load(ContainerBuilder builder)

        {

            //获取当前程序启动项程序集(*.dll)文件所在目录(文件夹)的绝对路径字符串(这里特指“..\bin\Debug\net7.0”)

            var basePath = AppContext.BaseDirectory;

            #region 带有接口层的服务注入

            //var servicesDllFile = Path.Combine(basePath, "CoreCms.Net.Services.dll");

            var repositoryDllFile = Path.Combine(basePath, "CoreCms.Net.Repository.dll");

            /*  if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))

            {

                var msg = "Repository.dllServices.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。";

                throw new Exception(msg);

            }*/

         

            // 获取 Service.dll 程序集服务,并注册

            /*var assemblysServices = Assembly.LoadFrom(servicesDllFile);

            //支持属性注入依赖重复

            builder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces().InstancePerDependency()

                .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

*/

            // 获取 Repository.dll 程序集服务,并注册

            var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);

            //支持属性注入依赖重复

            builder.RegisterAssemblyTypes(assemblysRepository).AsImplementedInterfaces().InstancePerDependency()

                .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

            #endregion

        }

    }

}

4 Program.cs

#region AutoFac注册============================================================================

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>

{

    //获取所有控制器类型并使用属性注入

    var controllerBaseType = typeof(ControllerBase);

    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly)

        .Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)

        .PropertiesAutowired();

    containerBuilder.RegisterModule(new AutofacModuleRegister());

});

#endregion

5 CoreCms.Net.IRepository.UnitOfWork.IUnitOfWork

using SqlSugar;

namespace CoreCms.Net.IRepository.UnitOfWork

{

    /// <summary>

    /// 【工作单元--类】

    /// <remarks>

    /// 摘要:

    ///     通过继承该接口的具体实现类中的方法成员,获取SqlSugarScope(用单例AddSingleton 单例)上下文中间件实例,从而为实现实体与表的CURD操作提供支撑。

    /// </remarks>

    /// </summary>

    public interface IUnitOfWork

    {

        #region 方法

        /// <summary>

        /// 【获取数据库数据端】

        /// <remarks>

        /// 摘要:

        ///     获取SqlSugarScope(用单例AddSingleton  单例)上下文中间件实例,该实例为通过 SqlSugar中间件实现实体与表的CURD操作提供支撑。

        /// </remarks>

        /// </summary>

        SqlSugarScope GetDbClient();

        /// <summary>

        /// 【事务开始】

        /// <remarks>

        /// 摘要:

        ///    该方法通过事务操作实现实现实体与表的CURD操作提供支撑,该方法主要指开启1个事务。

        /// </remarks>

        /// </summary>

        void BeginTran();

        /// <summary>

        /// 【事务提交】

        /// <remarks>

        /// 摘要:

        ///    该方法通过事务操作实现实现实体与表的CURD操作提供支撑,该方法主要指把1个事务中的所有操作进行提交到指定的数据库中。

        /// </remarks>

        /// </summary>

        void CommitTran();

        /// <summary>

        /// 【事务回滚】

        /// <remarks>

        /// 摘要:

        ///    该方法通过事务操作实现实现实体与表的CURD操作提供支撑,当把1个事务中的所有操作进行提交到指定的数据库的过程中如果出现异常时,则通过该方法实现回滚。

        /// </remarks>

        /// </summary>

        void RollbackTran();

        #endregion

    }

}

6 CoreCms.Net.IRepository.UnitOfWork.UnitOfWork

using CoreCms.Net.IRepository.UnitOfWork;

//using CoreCms.Net.Loging;

//using NLog;

using SqlSugar;

using SqlSugar.IOC;

namespace CoreCms.Net.Repository.UnitOfWork

{

    /// <summary>

    /// 【工作单元--类】

    /// <remarks>

    /// 摘要:

    ///     通过该类中的成员获取SqlSugarScope(用单例AddSingleton  单例)上下文中间件实例,从而为实现实体与表的CURD操作提供支撑。

    /// </remarks>

    /// </summary>

    public class UnitOfWork : IUnitOfWork

    {

        #region 拷贝构造方法与变量

        /// <summary>

        /// 【上下文中间件实例】

        /// <remarks>

        /// 摘要:

        ///    ISqlSugarClient( AddScoped  每次请求一个实例)上下文中间件实例,该实例为通过 SqlSugar中间件实现实体与表的CURD操作提供支撑。

        /// </remarks>

        /// </summary>

        private readonly ISqlSugarClient _sqlSugarClient;

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     通过该拷贝构造方法,对当前类中变量成员进行实例化。

        /// </remarks>

        /// </summary>

        public UnitOfWork()

        {

            _sqlSugarClient = DbScoped.SugarScope;

        }

        #endregion

        #region 方法

        /// <summary>

        /// 【获取数据库数据端】

        /// <remarks>

        /// 摘要:

        ///     获取SqlSugarScope(用单例AddSingleton  单例)上下文中间件实例,该实例为通过 SqlSugar中间件实现实体与表的CURD操作提供支撑。

        /// </remarks>

        /// </summary>

        public SqlSugarScope GetDbClient()

        {

            // 必须要as,后边会用到切换数据库操作

            return _sqlSugarClient as SqlSugarScope;

        }

        /// <summary>

        /// 【事务开始】

        /// <remarks>

        /// 摘要:

        ///    该方法通过事务操作实现实现实体与表的CURD操作提供支撑,该方法主要指开启1个事务。

        /// </remarks>

        /// </summary>

        public void BeginTran()

        {

            GetDbClient().BeginTran();

        }

        /// <summary>

        /// 【事务提交】

        /// <remarks>

        /// 摘要:

        ///    该方法通过事务操作实现实现实体与表的CURD操作提供支撑,该方法主要指把1个事务中的所有操作进行提交到指定的数据库中。

        /// </remarks>

        /// </summary>

        public void CommitTran()

        {

            try

            {

                GetDbClient().CommitTran();

            }

            catch (Exception ex)

            {

                GetDbClient().RollbackTran();

               // NLogUtil.WriteFileLog(LogLevel.Error, LogType.Web, "事务提交异常", "事务提交异常", new Exception("事务提交异常", ex));

                throw;

            }

        }

        /// <summary>

        /// 【事务回滚】

        /// <remarks>

        /// 摘要:

        ///    该方法通过事务操作实现实现实体与表的CURD操作提供支撑,当把1个事务中的所有操作进行提交到指定的数据库的过程中如果出现异常时,则通过该方法实现回滚。

        /// </remarks>

        /// </summary>

        public void RollbackTran()

        {

            GetDbClient().RollbackTran();

        }

        #endregion

    }

}

12 CoreCms.Net.Web.Admin.Controllers.SysRoleController

using Microsoft.AspNetCore.Mvc;

using System.ComponentModel;

using CoreCms.Net.IRepository;

namespace CoreCms.Net.Web.Admin.Controllers

{

    [ApiController]

    [Route("[controller]/[action]")]

    public class SysRoleController : ControllerBase

    {

        private readonly ISysRoleRepository _dal;

        public SysRoleController(ISysRoleRepository dal)

        {

            _dal = dal;

        }

        #region 获取列表============================================================

        [HttpPost]

        [Description("获取列表")]

        public async Task</*AdminUiCallBack*/ bool> GetPageList()

        {

            var v = await _dal.QueryPageAsync(null,"");

            return true;

        }

        #endregion

    }

}

对以上功能更为具体实现和注释见:230727_002CoreShop230628(逻辑分页、AutoFac注入、工作单元与仓储)。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/9813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云部署 ChatGLM2-6B 与 langchain+ChatGLM

1.ChatGLM2-6B 部署 更新系统 apt-get update 安装git apt-get install git-lfs git init git lfs install 克隆 ChatGLM2-6B 源码 git clone https://github.com/THUDM/ChatGLM2-6B.git 克隆 chatglm2-6b 模型 #进入目录 cd ChatGLM2-6B #创建目录 mkdir model #进入目录 cd m…

python机器学习(五)逻辑回归、决策边界、代价函数、梯度下降法实现线性和非线性逻辑回归

线性回归所解决的问题是把数据集的特征传入到模型中&#xff0c;预测一个值使得误差最小&#xff0c;预测值无限接近于真实值。比如把房子的其他特征传入到模型中&#xff0c;预测出房价&#xff0c; 房价是一系列连续的数值&#xff0c;线性回归解决的是有监督的学习。有很多场…

opencv-23 图像几何变换02-翻转-cv2.flip()

在 OpenCV 中&#xff0c;图像的翻转采用函数 cv2.flip()实现 &#xff0c;该函数能够实现图像在水平方向翻转、垂直方向翻转、两个方向同时翻转&#xff0c;其语法结构为&#xff1a; dst cv2.flip( src, flipCode )式中&#xff1a;  dst 代表和原始图像具有同样大小、类…

vite+vue3 css scss PC移动布局自适应

1. 安装 postcss-pxtorem 和 autoprefixer npm install postcss-pxtorem autoprefixer --save2. vite.config.js引入并配置 import postCssPxToRem from postcss-pxtorem import autoprefixer from autoprefixerexport default defineConfig({base: ./,resolve: {alias},plug…

前端面试题 —— React (三)

目录 一、对componentWillReceiveProps 的理解 二、React.forwardRef是什么&#xff1f;它有什么作用&#xff1f; 三、可以使用TypeScript写React应用吗&#xff1f;怎么操作&#xff1f; &#xff08;1&#xff09;如果还未创建 Create React App 项目 &#xff08;2&am…

Linux搭建Promtail + Loki + Grafana 轻量日志监控系统

一、简介 日志监控告警系统&#xff0c;较为主流的是ELK&#xff08;Elasticsearch 、 Logstash和Kibana核心套件构成&#xff09;&#xff0c;虽然优点是功能丰富&#xff0c;允许复杂的操作。但是&#xff0c;这些方案往往规模复杂&#xff0c;资源占用高&#xff0c;操作苦…

用Python合并多个文件为一个文本文件的方法代码

用Python合并多个文件为一个文本文件的方法代码 Python文件处理操作方便快捷&#xff0c;本文为大家提供的是如何用Python合并多个文本文件的代码示例。要把多个txt或是其它类型文件合并成一个&#xff0c;手动操作费时费力&#xff0c;不如自己动手写一个python代码来完成&…

UE4/5C++多线程插件制作(十六、Coroutines协程封装)

目录 准备 MTPCoroutines.h MTPCoroutines.cpp 我们要对协程继续封装制作: 协程是一种计算机程序组件,它允许在某个位置暂停执行,然后在稍后的时间点恢复执行。与传统的函数调用不同,协程可以被多次调用并且能够保留其内部状态,从而允许程序在执行到一定点时暂停,执行…

java中判断list是否为空

java中判断list是否为空是日常代码中经常遇到的问题。最近发现一个Utils提供的方法可以一步判断。 废话不多说&#xff0c;直接上代码&#xff01; ArrayList<String> arrayList new ArrayList<>(); System.out.println("集合1&#xff1a;" Collecti…

关于Android系统休眠跟串口读写的联系

问题描述&#xff1a;设备在进行rtk定位时&#xff0c;模块会通过串口同时进行读写操作。串口在读写时&#xff0c;如果息屏系统就会进入休眠&#xff0c;休眠的话CPU进入kill cpu状态。但是此时串口还在读写&#xff0c;这就导致出现一个意料外的问题&#xff0c;息屏只十几秒…

2-vi和vim的使用

vi和vim的区别 vi 是linux系统中内置的文本编辑器vim具有程序编辑能力 vi和vim常用的三种模式 正常模式 使用vim打开一个文件&#xff0c;就默认进入正常模式可以使用方向键【上下左右】来移动光标可以使用【删除字符/删除整行】来处理文件内容也可以使用【复制/粘贴】快捷键…

php 年月日 分组分页

//年月日 //分组 分页$type $this->request->type;$dateType "%Y-%m";//月$dateType1 "CONCAT(tmp.date,-01 00:00:00)";$dateType2 "CONCAT(LAST_DAY(CONCAT(tmp.date, -15)), 23:59:59)";if ($type day) {//日$dateType "%Y-…

Pytorch个人学习记录总结 03

目录 Transeforms的使用 常见的transforms Transeforms的使用 torchvision中的transeforms&#xff0c;主要是对图像进行变换&#xff08;预处理&#xff09;。from torchvision import transforms transeforms中常用的就是以下几种方法&#xff1a;&#xff08;Alt7可唤出…

小程序商城免费搭建之java商城 java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

pb:数据类型检查和转换函数

数据类型检查和转换函数 1、Asc() 功 能:得到字符串第一个字符的ASCII码整数值。 语 法:Asc ( string ) 参 数:string:要得到第一个字符ASCII值的字符串。 返回值:Integer。函数执行成功时返回string参数第一个字符的ASCII值,如果string参数的值为NULL,则Asc()函…

解决 The ‘more_itertools‘ package is required

在使用爬虫获取维基百科数据时看到了一个很好的项目&#xff1a; 博客&#xff1a;https://blog.51cto.com/u_15919249/5962100 项目地址&#xff1a;https://github.com/wjn1996/scrapy_for_zh_wiki 但在使用过程中遇到若干问题&#xff0c;记录一下&#xff1a; The ‘more_…

SpringBoot整合第三方 Druid、MybatisPlus、Mybatis

整合第三方技术 整合JUnit Respostory 注解&#xff1a;数据类 1、导入测试对应的starter 2、测试类使用 SpringBootTest 修饰 3、使用自动装配的形式添加要测试的对象 classes的属性 其实主要找的是SpringBootApplication中的SpringBootConfiguration这个注解。也就是配置…

python中去除字符串中指定的字符

去除字符串中特定字符&#xff08;但是只能删除头、尾指定字符&#xff09;&#xff1a; a 你好\n我是xx。\n\n\n print(a.strip(\n))# 你好 # 我是xx。 去除中间字符&#xff0c;可使用replace()函数&#xff1a; a 你好\n我是xx。\n\n\n print(a.replace(\n, ))# 你好我…

215.数组中的第K个最大元素-C++

题目来源&#xff1a;力扣 题目描述&#xff1a; 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法…

【微信小程序】通过监听 WebSocket 的状态变化来判断Socket是否已经建立连接

在微信小程序中&#xff0c;可以通过监听 WebSocket 的状态变化来判断是否已经建立连接。具体的操作步骤如下&#xff1a; 创建 WebSocket 对象并进行连接&#xff1a; var socket null; function connectWebSocket() {socket wx.connectSocket({url: wss://your-socket-ur…