共计 3597 个字符,预计需要花费 9 分钟才能阅读完成。
背景
从 2000 年开始,xml
作为数据交换格局开始风行,服务器拼接 xml
接口,客户端 js 获取 xml
内容,动静批改页面。
几年后,数据量更小的 json
代替了xml
。
挪动互联网到来后,因为客户端决裂,加剧了接口的泛滥。
一转眼,接口曾经玩了 20 年了。其余技术飞速发展,而前后端交互却始终是接口,没有什么翻新。
js 曾经有了import
、export
,为什么调用后端接口,不能像调用一个前端模块一样呢?
serverless,让这所有开始了变动。
亚马逊 lambda
提出了云函数的概念,不再应用 restful
的url
,但依然是基于 json
替换前后端数据。
uniCloud
最后也以反对云函数为开始,但咱们发现这仍不够优雅、简洁、直观、对立。
从 HBuilderX 3.4
开始,uniCloud
推出了“云对象”,让调用云端服务,真正变成像调用前端模块一样简略。
什么是云对象
云对象:服务器编写 API,客户端调用 API,不再开发传输 json 的接口。思路更清晰、代码更精简。
比方服务端编写一个云对象 news,该对象导出若干办法:add()、getList()、getDetailById()、softDel()、changeContent()、allowPublic()、addComment()、getComments()… 等办法。
客户端的 js 则能够间接 import
这个 news
云对象,而后间接调用 add
等办法。
服务器示例代码如下:
HBuilderX 中在 uniCloud/cloudfunctions 目录新建云函数 / 云对象,抉择类型为云对象,起名为 news。关上云对象入口index.obj.js
,增加一个 add 办法。
// 云对象名:news
module.exports = {add(title, content) {title = title.trim()
content = content.trim()
if(!title || !content) {
return {
errCode: 'INVALID_NEWS',
errMsg: '题目或内容不可为空'
}
}
// ... 其余逻辑
return {
errCode: 0,
errMsg: '创立胜利'
}
}
}
而后在客户端的 js 中,import
这个 news
对象,调用它的 add
办法。
const news = uniCloud.importObject('news') // 第一步导入云对象
async function add () {
try {const res = await news.add('title demo', 'content demo') // 导入云对象后就能够间接调用该对象的办法了,留神应用异步 await
uni.showToast({title: '创立胜利'})
} catch (e) {// 合乎 uniCloud 响应体标准 https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=resformat,主动抛出此谬误}
}
能够看到云对象的代码十分清晰,代码行数也只有 27 行。
而同样的逻辑,应用传统的接口方式则须要更多代码,见下:
// 传统形式调用云函数 - 云函数代码
// 云函数名:news
// 云函数入口 index.js 内容如下
'use strict';
exports.main = async (event, context) => {
const {
method,
params
} = event
switch(method) {
case 'add': {
let {
title,
content
} = params
title = title.trim()
content = content.trim()
if(!title || !content) {
return {
errCode: 'INVALID_NEWS',
errMsg: 'NEWS 题目或内容不可为空'
}
}
// ... 省略其余逻辑
return {
errCode: 0,
errMsg: '创立胜利'
}
}
}
return {
errCode: 'METHOD_NOT_FOUND',
errMsg: `Method[${method}] not found`
}
};
传统形式调用云函数 - 客户端代码
async function add () {
try {
const res = uniCloud.callFunction({
name: 'news',
data: {
method: 'add',
params: {
title: 'title demo',
content: 'content demo'
}
}
})
const {
errCode,
errMsg
} = res.result
if(errCode) {
uni.showModal({
title: '创立失败',
content: errMsg,
showCancel: false
})
return
}
uni.showToast({title: '创立胜利'})
} catch (e) {
uni.showModal({
title: '创立失败',
content: e.message,
showCancel: false
})
}
}
以上传统开发须要 68 行代码,比照云对象的 27 行代码,能够说“又丑又长”
更多弱小性能
1. 预处理与后处理
无论申请云对象的哪个办法,开始前都会通过 _before
办法,完结会执行 _after
办法。这有助于对立的提前校验和格式化谬误。
示例:
// news/index.obj.js
module.exports = {_before: function(){this.startTime = Date.now() // 在 before 内记录开始工夫并在 this 上挂载,以供后续流程应用
const methodName = this.getMethodName() // 获取以后申请的云对象办法名
if(methodName === 'add' && !this.getUniIdToken()) {throw new Error('token 不存在')
}
},
add: function(title = '', content ='') {if(title === 'abc') {throw new Error('abc 不是一个非法的 news 题目')
}
return {
errCode: 0,
errMsg: '创立胜利'
}
},
_after(error, result) {if(error) {throw error // 如果办法抛出谬误,也间接抛出不解决}
result.timeCost = Date.now() - this.startTime
return result
}
}
2. 云对象的返回值兼容 uniCloud 响应体标准
云对象返回值默认为uniCloud 响应体标准
,不便客户端对立拦挡谬误。
无论网络异样,还是 token 过期,都能够对立拦挡提醒。
详见 uniCloud 响应体标准
3. 主动显示交互界面
每次写客户端联网的代码时,开发者都免不了反复写一堆代码:先调用 loading 期待框,联网完结后再敞开 loading,如果服务器异样则弹出提示框。
原来的写法(22 行):
uni.showLoading({title: '联网中...'})
uni.request({
url: "xxxx",
success: (res) => {
uni.showToast({
title: '增加胜利',
icon: 'success',
mask: true,
duration: duration
});
},
fail: (err) => {
uni.showModal({
content: err.errMsg,
showCancel: false
});
},
complete: () => {uni.hideLoading();
}
});
当初,调用云对象的办法时,默认自带上述性能。
- 在申请联网开始时显示 loading 期待框,
- 完结后暗藏 loading
- 如果申请报错,显示弹窗(也可配置为显示 Toast)
const news = uniCloud.importObject('news') // 第一步导入云对象
try {await news.add('title demo', 'content demo') // 导入云对象后就能够间接调用该对象的办法了,留神应用异步 await
uni.showToast({title: '增加胜利'})
} catch (e) {}
如上,原来须要 23 行的代码,当初 7 行就能够搞定!
当然,这些 UI 策略都能够自定义。
- URL 化
为了历史兼容思考,云对象同时提供了 URL 化计划。开发者依然能够把一个云对象转换为一个 http
的url
接口。
总结
应用云对象带来的诸多益处:
- 更清晰的逻辑
- 更精简的代码
- 更少的合作老本(以及矛盾~)
- 客户端调用时在 ide 里有欠缺的代码提醒,办法参数均可提醒。(传输
json
可没法在ide
里提醒) - 主动反对 uniCloud 响应体标准,不便谬误拦挡和对立解决
更多云对象介绍,参见:https://uniapp.dcloud.net.cn/uniCloud/cloud-obj.html