vue3 实战之下发数据给设备并查询状态

先来看一段代码

javascript 复制代码
import axios from '@/utils/request'

const prefix = '/zeus/v1'

// 下发指令
const issueInstructions = ({ api, method, wifiSn, paramBody }) => {
  return axios.post(prefix + '/XHub/device/commonSet', {
    api,
    method,
    wifiSn,
    body: paramBody
  })
}

const obtainRemoteData = ({ wifiSn, taskId }) => {
  return axios.post(prefix + '/XHub/device/commonResp', {
    wifiSn,
    taskId
  })
}

const pollingSearch = async (params, timer = 0, pollTime = 5, timeInterval = 1000) => {
  const data = await obtainRemoteData(params)
  if (data) {
    return data
  } else {
    timer++
    if (timer < pollTime) {
      setTimeout(() => {
        pollingSearch(params, timer, (pollTime = 5), (timeInterval = 1000))
      }, timeInterval)
    } else {
      return null
    }
  }
}

const deviceCommunication = async (apiData) => {
  const { taskId } = await issueInstructions(apiData)
  const data = await pollingSearch({ ...apiData, taskId })
  return data
}

export { deviceCommunication }
javascript 复制代码
外面调用
const getTaskScheduling = async () => {
  const res = await deviceCommunication({
    wifiSn,
    api: '/zeus/v1/XHub/ai/getControlStrategy',
    method: 'get',
    paramBody: {
      wifiSn
    }
  })
  console.log('res', res)
}

这段代码实现了一个设备通信的逻辑,主要包括下发指令、轮询获取远程数据和设备通信的整体流程。下面我将逐段详细解释代码的功能和逻辑。


1. 引入依赖

javascript 复制代码
javascript
深色版本
import axios from '@/utils/request'

const prefix = '/zeus/v1'
  • axios 是一个基于 Promise 的 HTTP 请求库,通常用于与后端 API 交互。
  • @/utils/request 是项目中封装的 Axios 实例,可能包含一些全局配置(如请求拦截器、响应拦截器等)。
  • prefix 是 API 的基础路径,所有请求都会附加到这个路径前缀上。

2. 下发指令函数 issueInstructions

javascript 复制代码
javascript
深色版本
const issueInstructions = ({ api, method, wifiSn, paramBody }) => {
  return axios.post(prefix + '/XHub/device/commonSet', {
    api,
    method,
    wifiSn,
    body: paramBody
  })
}

功能:

该函数用于向服务器发送指令,触发设备执行某些操作。

参数说明:

  • api:指定的 API 接口名称。
  • method:调用的方法(可能是设备支持的操作类型,例如 "开关" 或 "查询状态")。
  • wifiSn:设备的唯一标识符(通常是设备的序列号或 MAC 地址)。
  • paramBody:具体的指令参数,传递给设备的数据。

返回值:

  • 使用 axios.post 发送 POST 请求到 /zeus/v1/XHub/device/commonSet,并返回一个 Promise。
  • 服务器会返回一个任务 ID (taskId),用于后续轮询查询结果。

3. 获取远程数据函数 obtainRemoteData

javascript 复制代码
javascript
深色版本
const obtainRemoteData = ({ wifiSn, taskId }) => {
  return axios.post(prefix + '/XHub/device/commonResp', {
    wifiSn,
    taskId
  })
}

功能:

该函数用于根据任务 ID 查询设备的响应数据。

参数说明:

  • wifiSn:设备的唯一标识符。
  • taskId:任务 ID,由 issueInstructions 返回。

返回值:

  • /zeus/v1/XHub/device/commonResp 发送 POST 请求,返回一个 Promise。
  • 如果任务已完成,服务器会返回设备的响应数据;否则返回空或其他状态。

4. 轮询函数 pollingSearch

csharp 复制代码
javascript
深色版本
const pollingSearch = async (params, timer = 0, pollTime = 5, timeInterval = 1000) => {
  const data = await obtainRemoteData(params)
  if (data) {
    return data
  } else {
    timer++
    if (timer < pollTime) {
      setTimeout(() => {
        pollingSearch(params, timer, (pollTime = 5), (timeInterval = 1000))
      }, timeInterval)
    } else {
      return null
    }
  }
}

功能:

该函数通过轮询的方式不断查询设备的响应数据,直到获取到数据或达到最大轮询次数。

参数说明:

  • params:包含 wifiSntaskId 的对象,用于查询设备数据。
  • timer:当前轮询次数,默认为 0。
  • pollTime:最大轮询次数,默认为 5 次。
  • timeInterval:每次轮询的时间间隔,默认为 1000 毫秒(1 秒)。

逻辑:

  1. 调用 obtainRemoteData 获取设备的响应数据。

  2. 如果成功获取到数据,则直接返回数据。

  3. 如果未获取到数据:

    • 增加轮询计数器 timer
    • 如果轮询次数小于最大轮询次数 (pollTime),则使用 setTimeout 延迟一段时间后再次调用自身(递归)。
    • 如果达到最大轮询次数,则返回 null,表示未能获取到数据。

5. 设备通信主函数 deviceCommunication

javascript 复制代码
javascript
深色版本
const deviceCommunication = async (apiData) => {
  const { taskId } = await issueInstructions(apiData)
  const data = await pollingSearch({ ...apiData, taskId })
  return data
}

功能:

这是整个设备通信的核心函数,负责完成以下两个步骤:

  1. 下发指令,获取任务 ID。
  2. 使用任务 ID 进行轮询,获取设备的响应数据。

参数说明:

  • apiData:包含 apimethodwifiSnparamBody 的对象,用于调用 issueInstructions

返回值:

  • 返回设备的最终响应数据(如果成功获取到)。
  • 如果轮询超时或未获取到数据,则返回 null

6. 导出模块

arduino 复制代码
javascript
深色版本
export { deviceCommunication }
  • deviceCommunication 函数导出,供其他模块使用。

完整流程总结

  1. 下发指令

    • 调用 issueInstructions,向设备发送操作指令。
    • 服务器返回一个任务 ID (taskId),用于后续查询。
  2. 轮询获取数据

    • 使用 pollingSearch 不断查询设备的响应数据。
    • 如果在最大轮询次数内获取到数据,则返回数据;否则返回 null
  3. 设备通信

    • deviceCommunication 整合了上述两个步骤,提供了一个简单的接口,供外部调用。

示例调用

假设我们需要控制某个设备打开灯,以下是调用示例:

javascript 复制代码
javascript
深色版本
import { deviceCommunication } from './path/to/file'

const apiData = {
  api: 'controlLight',
  method: 'turnOn',
  wifiSn: '1234567890ABCDEF',
  paramBody: {
    brightness: 100
  }
}

deviceCommunication(apiData).then(data => {
  if (data) {
    console.log('设备响应数据:', data)
  } else {
    console.log('未能获取设备响应数据')
  }
}).catch(error => {
  console.error('设备通信失败:', error)
})

优点

  1. 模块化设计

    • 每个函数职责明确,易于维护和扩展。
  2. 轮询机制

    • 提供了可靠的轮询逻辑,确保能够等待设备响应。
  3. 灵活性

    • 参数化设计使得函数可以适应不同的设备和指令。

  1. 轮询优化

    • 当前轮询使用 setTimeout,可以改为 setInterval 或更高效的轮询方式。
    • 添加取消轮询的机制(例如当用户手动停止操作时)。
  2. 超时时间配置

    • 当前轮询的最大次数和时间间隔是硬编码的,可以将其作为可配置参数。
相关推荐
计算机-秋大田11 分钟前
基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
PsG喵喵36 分钟前
用 Pinia 点燃 Vue 3 应用:状态管理革新之旅
前端·javascript·vue.js
鹏仔工作室36 分钟前
vue h5实现车牌号输入框
前端·javascript·vue.js
DT——1 小时前
Vue2和Vue3的区别
开发语言·javascript·vue.js
Python私教2 小时前
Vue 在现代 Web 开发中的优势
前端·javascript·vue.js
fridayCodeFly2 小时前
<KeepAlive>和<keep-alive>有什么区别
前端·javascript·vue.js
寻梦人121382 小时前
Vite管理的Vue3项目中monaco editer的使用以及组件封装
前端·javascript·vue.js·vscode
瓶子丶2 小时前
企业微信通讯录效果?拿捏!!!
vue.js·uni-app
洋茄子炒鸡蛋3 小时前
有没有一刻,突然平静地想离职(VUE中使用XLSX插件导入Excel文件,日期解析存在误差)
vue.js·excel
outsider_友人A3 小时前
手摸手带你封装Vue组件库(16)Carousel走马灯组件
前端·javascript·vue.js