说明
官网web页面可以查看云函数列表,但是云函数的具体代码无法直接查看到。
具体代码需要在HBuilderX上查看和编写,同时也是在HBuilderX上传代码,服务空间上的云函数只是收到你前端的调用请求后,帮你执行,然后把执行的结果返回给你前端。
这样就和后端服务器一样,代替了后端服务器。
官网文档:https://uniapp.dcloud.io/uniCloud/cf-functions
优势
1、安全
2、不需要URL
如果需要,可以把云函数url化,就是你的前端可以直接请求这个云函数的url,得到想要的结果。
见下 云函数url化
3、自带token
===================
创建云函数
1、创建项目
查看 https://www.yuque.com/yejielin/mypn47/adwtg6
2、创建云函数
输入名称
然后会新建一个同名的文件夹,里面有个index.js文件,就在这里编写云函数,下面是格式。
函数有两个参数
event 前端发送请求对象
event指的是触发云函数的事件,当uni客户端调用云函数时,event就是uni客户端调用云函数时传入的参数。
在uni项目中通过 uni.callfunction 调用云函数,传入的event参数,
和
云函数url化,你通过其他项目前端请求云函数,传入的event参数,
两个是完全不一样的。
比如uniCloud.callFunction({ name: ‘test’, data: { a: 1 }}) 的event:
event:{
name: 'test',
data: { a: 1 }
}
你前端请求的event:
{
path: 'HTTP请求路径,如 /hello',
httpMethod: 'HTTP请求方法,如 GET',
headers: {HTTP请求头},
queryStringParameters: {HTTP请求的Query,键值对形式},
body: 'POST方法的data属性,为JSON格式,要自己转一下',
isBase64Encoded: 'true or false,表示body是否为Base64编码'
}
headers 请求头:(注意:uniidtoken 是我自己加的,实际是没有这个属性)
context 上下文对象
context 对象包含了此处调用的调用信息和运行状态,可以用它来了解服务运行的情况
uniCloud会自动将uni客户端(uni.callfunction( )方法调用云函数)的操作系统(os)、运行平台(platform)、应用信息(appid)等注入context中,开发者可通过context获取每次调用的上下文
'use strict';
exports.main = async (event, context) => {
let clientPlatformL = context.PLATFORM // 平台信息,如果是云函数url化,这里是没有值的,可以自己设置,如context.PLATFORM = 'h5'
// 特殊信息
let clientIP = context.CLIENTIP // 发送请求的客户端ip信息
let clientUA = context.CLIENTUA // 客户端user-agent信息,如Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36
let spaceInfo = context.SPACEINFO // 当前云服务空间信息 {spaceId:'xxx',provider:'tencent'}
let source = context.SOURCE // 当前云函数被何种方式调用,
// "client" uni客户端uni.callFunction方式调用
// "http" 前端请求 云函数url化 的url方式
// "timing" 定时触发器调用
// "server" 由管理端调用,HBuilderX里上传并运行,仅阿里云支持,腾讯云这种方式调用也是client
// "function" 由其他云函数callFunction调用,仅阿里云支持,腾讯云这种方式调用也是client
// 下面4个,只有通过uni客户端uni.callFunction方式调用;云函数url化的场景下无法获取
let os = context.OS //客户端操作系统,返回值:android、ios等
let platform = context.PLATFORM //运行平台,返回值为 mp-weixin、app-plus等
let appid = context.APPID // manifest.json中配置的appid,可以手动设置
let deviceId = context.DEVICEID // 客户端标识,新增于HBuilderX 3.1.0,同uni-app客户端getSystemInfo接口获取的deviceId
}
3、上传云函数
调用云函数
1、uni-app 项目内调用
创新项目使用云环境时,云环境会给顶层的window对象添加一个 uniCloud 对象,很多额外的API都是这个对象提供的。
通过 uniCloud.callFunction 调用云函数
// promise方式(推荐)
uniCloud.callFunction({
name: 'test', // 云函数的名字,就是创建时输入的名字
data: { a: 1 } // 要传入云函数的参数,key固定是data,到时候会传给云函数的event参数
})
.then(res => {
console.log(res) // res 为云函数返回给我们的结果,其中有个属性result,这个就是云函数return 的内容
});
// callback方式
uniCloud.callFunction({
name: 'test',
data: { a: 1 },
success(){},
fail(){},
complete(){}
});
2、其他项目调用
需要将云函数url化,然后你自己的项目请求云函数的url即可,见下:云函数url化
云函数URL化
就是把云函数变成url的方式,给其他方法请求
https://uniapp.dcloud.io/uniCloud/http
===================
公共模块
在哪
云函数支持公共模块。多个云函数的共享部分,可以抽离为公共模块,然后被多个云函数引用。
如下图的 common 文件夹(这个文件夹是固定的,不能修改名字),这里就是存放公共模块,里面每个文件夹都是一个公共模块
如何使用
1、引用公共模块
新建一个云函数,通过 const xxx = require( ‘ 模块名 ‘ ) 引用。
模块名,就是common文件里面的文件夹名
是后端的CommonJS 模块化方案。
'use strict';
// uni-captcha 是uniCloud 提供的图形验证码模块
// 1、这里是通过 require 引入
const uniCaptcha = require('uni-captcha')
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ', event)
// 2、使用模块的方法,create是uniCaptcha里面编写的方法
let res = await uniCaptcha.create({
scene:'4',
deviceId:'123'
})
//返回数据给客户端
return res
};
2、更新依赖(重要)
光引用是没办法直接用的,上面的代码会报无法找到 uni-captcha 这个模块。
要给这个云函数更新依赖,首先右键点击这个引用了公共模块的云函数,点击管理
勾选你引用的公共依赖
成功后你的云函数会多出一个 node_modules 的nodejs模块管理,
以及在包管理 package.json 里面多出一个本函数的依赖
最后上传部署云函数,就可以正常使用了
===================
其他特性
1、冷启动 / 热启动
官方介绍
https://uniapp.dcloud.io/uniCloud/cf-functions?id=launchtype
1、按需激活
函数在不被触发的时候, 计算资源是不被激活的
【激活过程】:当一个云函数初次被触发时,其完整过程如下:
1、实例化计算实例
2、加载函数代码
3、启动 node
4、执行代码
2、冷启动 / 热启动 解释
【冷启动】:函数被调用时,执行这些完整步骤的过程一般称作冷启动, 冷启动的耗时长于热启动,一般在一秒出头。
【热启动】:如果函数实例和执行进程都被复用的情况下,一般被定义为热启动, 热启动没有性能问题。
【总结】:隔了很久不用,第一次用就会比较慢,然后立即访问第二次,则很快,毫秒级响应。
3、云服务器资源回收
1、如果一个云函数实例长时间没有被再次调用,则该计算实例会被回收;
2、后续再次调用该云函数时,就会再次触发云函数的冷启动
【资源回收时间间隔】:
1、阿里云是15分钟内没有第二次访问的云函数,就会被回收。
2、腾讯云是半小时。
4、执行中的问题
【云函数中的全局变量】:因为存在冷热启动的差异,云函数中的全局变量就可能出现每次不一样的情况。也就是云函数是无状态的。
5、建议
两家云厂商仍然在优化这个问题。目前如果开发者在意这个问题,给开发者的建议是:
1、使用 clientDB 可以减少遇到冷启动问题的概率
2、非高频访问的云函数,合并到高频云函数中。有的开发者使用纯单页方式编写云函数,即在一个云函数中通过路由处理实现了整个应用的所有后台逻辑。
比如登录和获取验证码,你可以写3个云函数,一个负责验证登录,一个负责提供验证码,一个负责验证验证码是否正确。
或者你也可以写1个云函数,里面包括了负责验证登录、提供验证码、验证验证码是否正确,只需要通过传入一个对象属性,用swith判断这个属性的值,来确定要进行什么操作,就可以了。(uni-id提供的uni-id-cf 云函数就是这样写的)
3、非高频访问的云函数,可以通过定时任务持续运行它(注意腾讯云可以使用这个方式完全避开冷启动,而阿里云的定时任务最短周期大于资源回收周期)
4、配置云函数的单实例多并发