uniapp - uniCloud 云函数

目录

云函数

分类

客户端和云函数的通信 

clientDB方式

 云对象方式

云对象

 云对象的Api

 内置特殊方法

预处理   _before 

后处理    _after

定时运行    _timing


云函数

概念

云函数是运行在云端的javascript代码,是基于Node.js的扩展

在Node API基础上,云函数环境内置了uniCloud对象,这个对象内置了网络、数据库等各种API。

每个云函数是一个js包,在云函数被调用时,由serverless调度系统分配硬件资源启动一个node环境来运行这个云函数。

 每个云函数是一个目录,其中普通云函数有index.js入口文件,云对象的入口文件则是index.obj.js

注意事项

  1. 云函数内使用commonJs规范,不可使用import、export

  2. 不同项目使用同一个服务空间时,不可使用同名云函数,同名云函数会相互覆盖

  3. 阿里云版服务器,暂不支持使用相对路径读取文件,比如fs.readFileSync('./info.txt'),可以使用绝对路径fs.readFileSync(path.resolve(__dirname, './info.txt'))

分类

云函数有若干子概念,包括 普通云函数、云对象、公共模块、clientDB的action云函数、uniCloud扩展库

  1. 普通云函数——通过传统json接口方式和客户端通信,客户端使用uniCloud.callfunction("")调用云函数
  2. 云对象——通过前端导入对象来操作的,客户端使用uniCloud.importObject("")导入云对象
  3. 公共模块:用于不同的云函数/云对象,抽取和共享相同代码
  4. action云函数——为了弥补clientDB客户端直接操作数据库的局限而设计的。
  5. uncCloud扩展库——为了裁剪和控制云函数体积而设计的,避免增大每个云函数的体积。
	
|——— cloudfunctions               云函数目录
|   │───common                    云函数公用模块目录 详情
|   |   └──hello-common           云函数公用模块
|   |      │──index.js            公用模块代码
|   |      └──package.json        公用模块package.json
|   │───uni-clientDB-actions
|   │      └──new_action.js       clientDB action代码 详情
|   │───function-name             云函数目录
|   │     │──index.js             云函数代码
|   │     └──package.json         包含云函数的配置信息,如url化、定时设置、可用内存等内容 详情
|   └───object-name               云对象目录
|         │──index.obj.js         云对象代码
|         └──package.json         包含云对象的配置信息,可用内存等内容 详情
	

客户端和云函数的通信 

云函数是uniCloud的基础,本质上clientDB和云对象都是建立在云函数上针对特定场景的优化。

  1. clientDB针对的场景是数据库操作,它优化了可以不写或少写服务器代码。
  2. 云对象针对的场景是非数据库操作或不宜前端暴露的数据库操作时,和uni-app客户端的通信方式。它优化了代码结构,更精简、简单

clientDB方式

 clientDB分API方式和组件方式

//API方式 客户端js直接操作云数据库,查询list表的数据。无需服务器代码
const db = uniCloud.database() // 获取云数据库的引用
db.collection('list').get()
  .then((res)=>{
    // res 为数据库查询结果
  }).catch((err)=>{
    console.log(err); 
  })

clientDB适用情况:

如果客户端使用uni-app开发,且向uniCloud服务空间的请求主要是为了操作云数据库(增删改查),那么推荐clientDB方式,由uni-app客户端直接操作云数据库。

 如果操作数据库的同时,还需要同时执行一些云函数,可以使用clientDB的action云函数。

clientDB不适用的情况:

  1. 请求不操作云数据库,比如向外部web系统发送请求,操作redis、删除云文件等 
  2. 操作的云数据库请求不希望暴露在前端
  3. 数据库表和字段数量多而接口数量少。给每个数据配置权限的工作量超过了控制少数接口权限的工作量
  4. 权限体系较复杂,除了用户和管理员外还有较多其他权限条件或动态权限。此时在schema和action中编写代码复杂度超过了写接口。

 云对象方式

云对象和clientDB最大的区别,是云对象把数据库操作(以及其他逻辑)封装在云对象的方法里面。仍需在客户端和云端分别写代码,但应用场景不受限制,clientDB不适应的它都适应。

// 云端云对象代码,云对象名称:testco,有一个sum方法

module.exports = {
	sum(a, b) {
		// 此处省略a和b的有效性校验
		return a + b
	}
}
//然后在客户端的js中,import这个testco对象,调用它的sum方法

const testco = uniCloud.importObject('testco') //第一步导入云对象
async function sum () { //注意方法或生命周期需使用async异步方式
	try {
		const res = await testco.sum(1,2) //导入云对象后就可以直接调用该对象的方法了,注意使用异步await
		console.log(res) // 结果是3
	} catch (e) {
		console.log(e)
	}
}

云对象

背景:20年前,restful接口开发流行,服务器编写接口,客户端调用接口,传输json

现在:云对象,服务器编写API,客户端调用API,不再开发传输Json的接口,思路更清晰,代码更精简。

比如:服务端编写一个云对象todo,该对象有add、get、remove、update等方法。客户端的js则可以直接import这个todo云对象,直接调用add等方法

// 云对象名:todo
module.exports = {
	add(title, content) {
		title = title.trim()
		content = content.trim()
		if(!title || !content) {
			return {
				errCode: 'INVALID_TODO',
				errMsg: 'TODO标题或内容不可为空'
			}
		}
		// ...其他逻辑
		return {
			errCode: 0,
			errMsg: '创建成功'
		}
	}
}
// 然后在客户端的js中,import这个todo对象,调用它的add方法

const todo = uniCloud.importObject('todo') //第一步导入云对象
async function addTodo () {
	try {
		const res = await todo.add('title demo', 'content demo') //导入云对象后就可以直接调用该对象的方法了,注意使用异步await
		uni.showToast({
			title: '创建成功'
		})
	} catch (e) {
		// 符合uniCloud响应体规范 https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=resformat,自动抛出此错误 
		uni.showModal({
			title: '创建失败',
			content: e.errMsg,
			showCancel: false
		})
	}
}

 云对象的Api

简介@intro | uni-app官网

 内置特殊方法

所有_开头的方法都是私有方法,客户端不可访问。也就是客户端调用云对象时不能调用_开头的方法

  1. _before  
  2. _after    
  3. _timing

预处理   _before 

用于调用常规方法之前进行预处理,一般用于拦截器,统一的身份验证,参数校验等。

//疑问: this.getUniIdToken() 为null   不显示错误提示
module.exports = {
	_before: function(){
		const methodName = this.getMethodName()
		if(methodName === 'add' && !this.getUniIdToken()) {
			throw new Error('token不存在')
		}
	},
	add: function(title = '', content = '') {
		return {
			errCode: 0,
			errMsg: '创建成功'
		}
	}
}

后处理    _after

云对象内可以创建一个特殊的方法_after用来再加工处理本次调用方法的返回结果或者抛出的错误

// todo/index.obj.js    没看出效果  T.T
module.exports = {
	_before: function(){
		this.startTime = Date.now() // 在before内记录开始时间并在this上挂载,以供后续流程使用
	},
	add: function(title = '', content = '') {
		if(title === 'abc') {
			throw new Error('abc不是一个合法的todo标题')
		}
		return {
			errCode: 0,
			errMsg: '创建成功'
		}
	},
	_after(error, result) {
		if(error) {
			throw error // 如果方法抛出错误,也直接抛出不处理
		}
		result.timeCost = Date.now() - this.startTime
		return result
	}
}

定时运行    _timing

uni-app官网

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值