# an-function

一个包含 JavaScript 常用工具函数的库，提供日期处理、文件下载、WebSocket 连接等实用功能。

## 安装

```bash
npm install an-function
```

## 使用方法

```javascript
// ES6 模块导入
import { getLengthArray, deepClone, chinaDate } from "an-function";

// CommonJS 导入
const { getLengthArray, deepClone, chinaDate } = require("an-function");
```

## API 文档

### getLengthArray

生成一个从 1 到指定数字的数组。

**参数:**

- `number` (number, 可选): 要生成的数组长度，默认为 0。

**返回值:**

- `number[]`: 一个从 1 到 `number` 的数组。

**示例:**

```javascript
import { getLengthArray } from "an-function";

// 生成 [1, 2, 3, 4, 5]
const arr = getLengthArray(5);
console.log(arr); // [1, 2, 3, 4, 5]
```

### deepClone

创建一个对象的深拷贝。

**参数:**

- `obj` (Object): 要拷贝的对象。
- `hash` (WeakMap, 可选): 用于处理循环引用的 WeakMap，默认为新的 WeakMap。
- `copyContructor` (boolean, 可选): 是否拷贝构造函数，默认为 false。

**返回值:**

- `Object`: 对象的深拷贝。

**特性:**

- 支持处理循环引用
- 支持基本类型、Date、RegExp 对象
- 如果浏览器支持 structuredClone，会优先使用它

**示例:**

```javascript
import { deepClone } from "an-function";

const obj = {
  a: 1,
  b: { c: 2 },
  d: new Date(),
  e: /test/g,
};
const clonedObj = deepClone(obj);
```

### chinaDate

将日期格式化为中国日期格式。

**参数:**

- `times` (string|Date|null|number, 可选): 要格式化的日期。如果为 null 或 undefined，则使用当前日期。
- `fengefu` (string, 可选): 用于格式化日期的分隔符，默认为 '-'。

**返回值:**

- `Object`: 一个包含各种日期格式和组件的对象：
  - `fengefu`: 分隔符
  - `newDate`: 日期对象
  - `nian`: 年份
  - `yue`: 月份（两位数）
  - `ri`: 日（两位数）
  - `shi`: 小时（两位数）
  - `fen`: 分钟（两位数）
  - `miao`: 秒（两位数）
  - `date`: 完整日期时间字符串 (YYYY-MM-DD HH:MM:SS)
  - `date0`: 当天 00:00:00 的日期时间字符串
  - `date59`: 当天 23:59:59 的日期时间字符串
  - `nyr`: 日期部分 (YYYY-MM-DD)
  - `sfm`: 时间部分 (HH:MM:SS)
  - `number`: 时间戳
  - `get0`: 当天 00:00:00 的时间戳
  - `get59`: 当天 23:59:59 的时间戳

**示例:**

```javascript
import { chinaDate } from "an-function";

// 使用当前日期
const today = chinaDate();
console.log(today.nyr); // 例如 "2023-11-22"
console.log(today.sfm); // 例如 "14:30:45"

// 使用指定日期
const specificDate = chinaDate("2023/11/22");
console.log(specificDate.date); // "2023-11-22 00:00:00"

// 使用斜杠作为分隔符
const dateWithSlash = chinaDate(new Date(), "/");
console.log(dateWithSlash.nyr); // 例如 "2023/11/22"
```

### getUrlParams

将 URL 参数解析为对象。

**参数:**

- `url` (string, 可选): URL 字符串。如果未提供，则使用当前页面的 URL。

**返回值:**

- `Object`: 一个包含解析后的 URL 参数的对象。

**示例:**

```javascript
import { getUrlParams } from "an-function";

// 假设当前 URL 是 "https://example.com?name=John&age=30"
const params = getUrlParams();
console.log(params); // { name: "John", age: "30" }

// 解析指定 URL
const customParams = getUrlParams("https://example.com?product=phone&color=black");
console.log(customParams); // { product: "phone", color: "black" }
```

### aDownLoad

通过创建一个锚点元素触发文件下载。

**参数:**

- `href` (string): 要下载的文件的 URL。
- `fileName` (string, 可选): 要下载的文件名，默认为空字符串。

**示例:**

```javascript
import { aDownLoad } from "an-function";

// 下载一个文件
aDownLoad("https://example.com/file.pdf", "document.pdf");
```

### aDownLoad2

从 Blob 响应中触发文件下载。

**参数:**

- `response` (Blob): 要下载的 Blob 响应。
- `fileName` (string, 可选): 要下载的文件名，默认为空字符串。

**示例:**

```javascript
import { aDownLoad2 } from "an-function";

// 假设从 API 获取了一个 Blob 响应
fetch("https://example.com/api/download")
  .then((response) => response.blob())
  .then((blob) => {
    aDownLoad2(blob, "downloaded-file.pdf");
  });
```

### objKeysHasValue

检查对象中的某些或所有指定键是否有值。

**参数:**

- `obj` (Object, 可选): 要检查的对象，默认为空对象。
- `keys` (string[], 可选): 要检查的键，默认为空数组。
- `type` (string, 可选): 检查类型，'some' 表示至少有一个键有值，'all' 表示所有键都有值，默认为 'some'。

**返回值:**

- `boolean`: 如果条件满足，返回 `true`，否则返回 `false`。

**示例:**

```javascript
import { objKeysHasValue } from "an-function";

const user = {
  name: "John",
  age: 30,
  email: "",
};

// 检查是否至少有一个键有值
const hasSomeValues = objKeysHasValue(user, ["name", "email"], "some");
console.log(hasSomeValues); // true，因为 'name' 有值

// 检查是否所有键都有值
const hasAllValues = objKeysHasValue(user, ["name", "email"], "all");
console.log(hasAllValues); // false，因为 'email' 没有值
```

### anWebSocket

WebSocket 连接管理类，提供自动重连、心跳检测等功能。

**构造函数参数:**

- `options` (Object): 配置选项对象
  - `url` (string, 必须): WebSocket 服务器 URL
  - `sendMessage` (any, 可选): 连接成功后要发送的消息
  - `webSocketBack` (Function, 可选): 接收消息的回调函数
  - `pingTimeout` (number, 可选): 发送心跳的间隔时间（毫秒），默认为 10000
  - `pongTimeout` (number, 可选): 等待心跳响应的超时时间（毫秒），默认为 8000
  - `reconnectTimeout` (number, 可选): 重连间隔时间（毫秒），默认为 4000
  - `pingMsg` (string, 可选): 心跳消息内容，默认为 'heartbeat'
  - `repeatLimit` (number, 可选): 最大重连次数，默认为 null（无限）
  - `showLog` (boolean, 可选): 是否显示日志，默认为 false

**方法:**

- `send(msg)`: 发送消息
- `close(permanently = false)`: 关闭连接，permanently 为 true 时永久关闭不再重连
- `destroy()`: 永久关闭连接
- `setEventHandlers(handlers)`: 设置事件处理函数
- `getState()`: 获取当前连接状态
- `isConnected()`: 检查是否已连接
- `getActiveConnections()`: 获取当前活动连接数

**示例:**

```javascript
import { anWebSocket } from "an-function";

const ws = new anWebSocket({
  url: "wss://example.com/socket",
  sendMessage: { type: "auth", token: "user-token" },
  webSocketBack: (event) => {
    console.log("收到消息:", event.data);
  },
  showLog: true,
});

// 发送消息
ws.send({ type: "message", content: "Hello!" });

// 设置事件处理函数
ws.setEventHandlers({
  onopen: () => console.log("连接已打开"),
  onclose: () => console.log("连接已关闭"),
});

// 关闭连接
ws.close();

// 永久关闭
ws.destroy();
```

### fileToBase64

将文件转换为 base64 字符串。

**参数:**

- `file` (File): 要转换的文件对象。

**返回值:**

- `Promise<string>`: 解析为 base64 字符串的 Promise。

**示例:**

```javascript
import { fileToBase64 } from "an-function";

// 假设有一个文件输入元素
const fileInput = document.getElementById("fileInput");
fileInput.addEventListener("change", async (e) => {
  const file = e.target.files[0];
  if (file) {
    try {
      const base64String = await fileToBase64(file);
      console.log(base64String);
      // 可以将 base64 字符串用于图片预览或上传
    } catch (error) {
      console.error("转换失败");
    }
  }
});
```

# anInterval 函数用法说明代替 window.setInterval

# anTimeout 函数用法说明代替 window.setTimeout（用法同 anInterval）

`anInterval` 是一个使用 Web Workers 实现的自定义间隔函数。它返回一个包含 `on` 和 `off` 方法的对象，用于设置和清除定时器。

## 方法

### on(fn, time)

- **参数**
  - `fn` (Function): 定时器触发时要执行的回调函数。
  - `time` (Number): 定时器的时间间隔，单位为毫秒。
- **返回值**
  - (String): 定时器的唯一标识符，用于后续清除定时器。
- **用法**
- `on(fn, time)`
  检查 Worker 是否存在，如果不存在则创建 Worker。
  生成一个唯一的定时器标识符。
  将标识符和回调函数存储在 listeners Map 中。
  向 Worker 发送消息，传递标识符和时间间隔。
- `off(id)`
  检查 listeners Map 中是否存在该标识符。
  如果存在，则删除该标识符及其对应的回调函数。
  向 Worker 发送消息，指示清除定时器。

```javascript
// 创建一个定时器，每隔1秒触发一次
const id = anInterval.on(() => {
  console.log("每秒触发一次");
}, 1000);

// 5秒后清除定时器
setTimeout(() => {
  anInterval.off(id);
  console.log("定时器已清除");
}, 5000);
```
