先来看一段代码
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
:包含wifiSn
和taskId
的对象,用于查询设备数据。timer
:当前轮询次数,默认为 0。pollTime
:最大轮询次数,默认为 5 次。timeInterval
:每次轮询的时间间隔,默认为 1000 毫秒(1 秒)。
逻辑:
-
调用
obtainRemoteData
获取设备的响应数据。 -
如果成功获取到数据,则直接返回数据。
-
如果未获取到数据:
- 增加轮询计数器
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
}
功能:
这是整个设备通信的核心函数,负责完成以下两个步骤:
- 下发指令,获取任务 ID。
- 使用任务 ID 进行轮询,获取设备的响应数据。
参数说明:
apiData
:包含api
、method
、wifiSn
和paramBody
的对象,用于调用issueInstructions
。
返回值:
- 返回设备的最终响应数据(如果成功获取到)。
- 如果轮询超时或未获取到数据,则返回
null
。
6. 导出模块
arduino
javascript
深色版本
export { deviceCommunication }
- 将
deviceCommunication
函数导出,供其他模块使用。
完整流程总结
-
下发指令:
- 调用
issueInstructions
,向设备发送操作指令。 - 服务器返回一个任务 ID (
taskId
),用于后续查询。
- 调用
-
轮询获取数据:
- 使用
pollingSearch
不断查询设备的响应数据。 - 如果在最大轮询次数内获取到数据,则返回数据;否则返回
null
。
- 使用
-
设备通信:
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)
})
优点
-
模块化设计:
- 每个函数职责明确,易于维护和扩展。
-
轮询机制:
- 提供了可靠的轮询逻辑,确保能够等待设备响应。
-
灵活性:
- 参数化设计使得函数可以适应不同的设备和指令。
-
轮询优化:
- 当前轮询使用
setTimeout
,可以改为setInterval
或更高效的轮询方式。 - 添加取消轮询的机制(例如当用户手动停止操作时)。
- 当前轮询使用
-
超时时间配置:
- 当前轮询的最大次数和时间间隔是硬编码的,可以将其作为可配置参数。