×
微信小程序开发教程手册文档体验微信小程序微信小程序 框架MINA 目录结构小程序配置逻辑层(App Service)微信小程序 注册程序微信小程序 场景值微信小程序 注册页面微信小程序 路由微信小程序 模块化小程序 API视图层(View)微信小程序 WXML微信小程序 数据绑定微信小程序 列表渲染微信小程序 条件渲染微信小程序 模板微信小程序 事件微信小程序 引用微信小程序 WXS微信小程序 WXS模块微信小程序 变量微信小程序 注释微信小程序 运算符微信小程序 语句微信小程序 数据类型微信小程序 基础类库微信小程序 WXSS微信小程序 组件微信小程序 基础库微信小程序 兼容微信小程序 运行机制性能微信小程序 性能Trace工具微信小程序 优化建议微信小程序 组件

视图容器

wxapp视图容器 viewwxapp视图容器 scroll-viewwxapp视图容器 swiperwxapp视图容器 movable-areawxapp视图容器 cover-view

基础内容

wxapp内容组件 iconwxapp内容组件 textwxapp内容组件 rich-textwxapp内容组件 progress表单组件wxapp表单组件 buttonwxapp表单组件 checkboxwxapp表单组件 formwxapp表单组件 inputwxapp表单组件 labelwxapp表单组件 pickerwxapp表单组件 picker-viewwxapp表单组件 radiowxapp表单组件 sliderwxapp表单组件 switchwxapp表单组件 textarea

导航

wxapp导航 navigator

媒体组件

wxapp媒体组件 audiowxapp媒体组件 imagewxapp媒体组件 videowxapp媒体组件 camera

地图

wxapp地图 map

画布

wxapp画布 canvas

开放数据

wxapp开放数据 open-datawxapp承载网页 web-view

客服会话

wxapp客服会话 contact-buttonAPI网络微信小程序API 发起请求微信小程序API 上传、下载微信小程序API Websocket

媒体

微信小程序API 图片微信小程序API 录音微信小程序API 音频播放控制微信小程序API 音乐播放控制微信小程序API 背景音频播放管理微信小程序API 音频组件控制微信小程序API 视频微信小程序API 视频组件控制微信小程序API 相机组件控制

文件

微信小程序API 文件

数据

微信小程序API 数据缓存

位置

微信小程序API 获取位置微信小程序API 查看位置微信小程序API 地图组件控制设备微信小程序API 系统信息微信小程序API 网络状态微信小程序API 加速度计微信小程序API 罗盘微信小程序API 拨打电话微信小程序API 扫码微信小程序API 剪贴板微信小程序API 蓝牙微信小程序API iBeacon微信小程序API 屏幕亮度微信小程序API 用户截屏事件微信小程序API 振动微信小程序API 手机联系人

界面

微信小程序API 交互反馈微信小程序API 设置导航条微信小程序API 设置置顶信息微信小程序API 导航微信小程序API 动画微信小程序API 位置绘图微信小程序API 绘图·介绍微信小程序API 绘图·坐标系微信小程序API 绘图·渐变微信小程序API 绘图·颜色微信小程序API 绘图上下文微信小程序API 绘图·创建并返回上下文微信小程序API 绘图·绘制画布微信小程序API 绘图·导出图片微信小程序API 绘图·设置填充样式微信小程序API 绘图·设置线条样式微信小程序API 绘图·设置阴影样式微信小程序API 绘图·创建线性渐变微信小程序API 绘图·创建圆形渐变微信小程序API 绘图·创建颜色渐变点微信小程序API 绘图·设置线条宽度微信小程序API 绘图·设置线条端点样式微信小程序API 绘图·设置线条交点样式微信小程序API 绘图·设置最大倾斜微信小程序API 绘图·创建矩形微信小程序API 绘图·填充矩形微信小程序API 绘图·画一个矩形微信小程序API 绘图·clearRect微信小程序API 绘图·填充路径微信小程序API 绘图·描边路径微信小程序API 绘图·开始路径微信小程序API 绘图·关闭路径微信小程序API 绘图·moveTo微信小程序API 绘图·lineTo微信小程序API 绘图·画弧线微信小程序API 绘图·quadraticCurveTo微信小程序API bezierCurveTo微信小程序API 绘图·scale微信小程序API 绘图·rotate微信小程序API 绘图·translate微信小程序API 绘图·设置字号微信小程序API 绘图·绘制文本微信小程序API 绘图·文字对齐微信小程序API 绘图·文字水平对齐微信小程序API 绘图·drawImage微信小程序API 绘图·setGlobalAlpha微信小程序API 绘图·保存/恢复微信小程序API 绘图·draw微信小程序API 绘图·getActions微信小程序API 绘图·clearActions微信小程序API 绘图·measureText微信小程序API 绘图·globalCompositeOperation微信小程序API 绘图·arcTo微信小程序API 绘图·strokeText微信小程序API 绘图·lineDashOffset微信小程序API 绘图·createPattern微信小程序API 下拉刷新

WXML节点信息

微信小程序API WXML节点信息

第三方平台

微信小程序API 第三方平台

开放接口

微信小程序API 登录微信小程序API 签名加密微信小程序API 授权微信小程序API 用户信息微信小程序API 微信支付微信小程序API 模板消息

微信小程序API 客服消息

微信小程序API 接收消息和事件微信小程序API 发送客服消息微信小程序API 转发消息微信小程序API 临时素材接口微信小程序API 接入指引微信小程序API 转发微信小程序API 二维码微信小程序API 收货地址微信小程序API 卡券微信小程序API 设置微信小程序API 微信运动微信小程序API 打开小程序微信小程序API 获取发票抬头微信小程序API 生物认证

数据

常规分析

微信小程序API 数据概况微信小程序API 访问分析微信小程序API 用户画像

自定义分析

微信小程序API 自定义数据上报

更新

微信小程序API getUpdateManager

拓展接口

微信小程序 拓展接口

多线程

微信小程序API createWorker

调试接口

微信小程序API 打开/关闭调试

工具

微信小程序工具 概览微信小程序工具 界面微信小程序工具 设置微信小程序工具 项目预览微信小程序工具 快捷键微信小程序工具 代码编辑微信小程序工具 程序调试微信小程序工具 特殊API的调试微信小程序工具 命令行调用微信小程序工具 HTTP调用微信小程序工具 代码片段微信小程序工具 第三方平台微信小程序工具 创建插件项目微信小程序工具 代码托管微信小程序工具 素材管理微信小程序工具 下载微信小程序工具 细节点微信小程序工具 beta版本下载微信小程序工具 Git版本管理微信小程序工具 体验评分微信小程序工具 npm支持

微信小程序 云开发

微信小程序云开发 基础

微信小程序云开发指引

微信小程序云开发 开发指引微信小程序云开发 控制台微信小程序云开发 初始化微信小程序云开发 数据库微信小程序云开发 存储微信小程序云开发 云函数微信小程序云开发参考信息

微信小程序云开发API 小程序端

微信小程序云开发API 初始化微信小程序云开发 数据库API数据库API database数据库API collection数据库API collection.doc数据库API collection.get数据库API doc.get数据库API collection.add数据库API collection.update数据库API doc.update数据库API doc.set数据库API doc.remove数据库API collection.count数据库API collection.where数据库API collection.orderBy数据库API collection.limit数据库API collection.skip数据库API collection.field数据库API db.command数据库API db.RegExp数据库API db.serverDate数据库API db.Geo数据库API 查询筛选条件数据库API 查询指令数据库API 更新指令数据库API get方法数据库API update数据库API remove微信小程序云开发API 服务端云开发服务端API 初始化云开发服务端API 工具类云开发服务端API 数据库服务端数据库API database服务端数据库API collection服务端数据库API collection.doc服务端数据库API collection.get服务端数据库API doc.get服务端数据库API collection.add服务端数据库API collection.update服务端数据库API collection.remove服务端数据库API doc.update服务端数据库API doc.set服务端数据库API doc.remove服务端数据库API collection.count服务端数据库API collection.where服务端数据库API collection.orderBy服务端数据库API collection.limit服务端数据库API collection.skip服务端数据库API collection.field服务端数据库API db.command服务端数据库API db.RegExp服务端数据库API db.serverDate服务端数据库API db.Geo服务端数据库API 查询筛选条件服务端数据库API 查询指令服务端数据库API 更新指令服务端数据库API db.createCollection服务端数据库API update服务端数据库API remove云开发服务端API 存储服务端存储API uploadFile服务端存储API downloadFile服务端存储API getTempFileURL服务端存储API deleteFile微信小程序开发文档-腾讯云支持微信小程序 联系我们微信小程序 Q&A微信小程序设计规范微信小程序设计规范(1) 友好礼貌微信小程序设计规范(2) 清晰明确微信小程序设计规范(3) 便捷优雅微信小程序设计规范(4) 统一稳定微信小程序设计规范(5) 视觉规范微信小程序源码分享微信小游戏开发手册 

微信小程序云开发云函数


云函数即在云端(服务器端)运行的函数。在物理设计上,一个云函数可由多个文件组成,占用一定量的 CPU 内存等计算资源;各云函数完全独立;可分别部署在不同的地区。开发者无需购买、搭建服务器,只需编写函数代码并部署到云端即可在小程序端调用,同时云函数之间也可互相调用。

一个云函数的写法与一个在本地定义的 JavaScript 方法无异,代码运行在云端 Node.js 中。当云函数被小程序端调用时,定义的代码会被放在 Node.js 运行环境中执行。我们可以如在 Node.js 环境中使用 JavaScript 一样在云函数中进行网络请求等操作,而且我们还可以通过云函数后端 SDK 搭配使用多种服务,比如使用云函数 SDK 中提供的数据库和存储 API 进行数据库和存储的操作,这部分可参考数据库存储后端 API 文档。

云开发的云函数的独特优势在于与微信登录鉴权的无缝整合。当小程序端调用云函数时,云函数的传入参数中会被注入小程序端用户的 openid,开发者无需校验 openid 的正确性因为微信已经完成了这部分鉴权,开发者可以直接使用该 openid。

接下来,我们将逐步学习以下内容:

  • 我的第一个云函数
  • 获取小程序用户信息
  • 异步返回结果
  • 使用 wx-server-sdk
  • 在开发者工具中管理云函数
  • 测试、日志与监控
  • 注意事项

我的第一个云函数

我们以定义一个将两个数字相加的函数作为我们第一个云函数的示例。

在项目根目录找到 project.config.json 文件,新增 cloudfunctionRoot 字段,指定本地已存在的目录作为云函数的本地根目录

示例:

{
   "cloudfunctionRoot": "./functions/"
}

project.config.json 的其他配置,详见项目配置文件

完成指定之后,云函数的根目录的图标会变成 “云目录图标”,云函数根目录下的第一级目录(云函数目录)是与云函数名字相同的,如果对应的线上环境存在该云函数,则我们会用一个特殊的 “云图标” 标明

接着,我们在云函数根目录上右键,在右键菜单中,可以选择创建一个新的 Node.js 云函数,我们将该云函数命名为 add。开发者工具在本地创建出云函数目录和入口 index.js 文件,同时在线上环境中创建出对应的云函数。创建成功后,工具会提示是否立即本地安装依赖,确定后工具会自动安装 wx-server-sdk。我们可以看到类似如下的一个云函数模板:

const cloud = require('wx-server-sdk')
// 云函数入口函数
exports.main = async (event, context) => {

}

云函数的传入参数有两个,一个是 event 对象,一个是 context 对象。event 指的是触发云函数的事件,当小程序端调用云函数时,event 就是小程序端调用云函数时传入的参数,外加后端自动注入的小程序用户的 openid 和小程序的 appid。context 对象包含了此处调用的调用信息和运行状态,可以用它来了解服务运行的情况。在模板中也默认 require 了 wx-server-sdk,这是一个帮助我们在云函数中操作数据库、存储以及调用其他云函数的微信提供的库,关于 wx-server-sdk 的使用我们在另一个章节讲述。

我们填充一下模板:

exports.main = async (event, context) => {
  return {
    sum: event.a + event.b
  }
}

本段代码的意思是将传入的 a 和 b 相加并作为 sum 字段返回给调用端。

在小程序中调用这个云函数前,我们还需要先将该云函数部署到云端。在云函数目录上右键,在右键菜单中,我们可以将云函数整体打包上传并部署到线上环境中。

部署完成后,我们可以在小程序中调用该云函数:

wx.cloud.callFunction({
  // 云函数名称
  name: 'add',
  // 传给云函数的参数
  data: {
    a: 1,
    b: 2,
  },
  success: function(res) {
    console.log(res.result) // 3
  },
  fail: console.error
})

当然,Promise 风格的调用也是支持的:

wx.cloud.callFunction({
  // 云函数名称
  name: 'add',
  // 传给云函数的参数
  data: {
    a: 1,
    b: 2,
  },
})
.then(res => {
  console.log(res.result) // 3
})
.catch(console.error)

那么到这里,我们就成功创建了我们的第一个云函数,并在小程序中成功调用!

接下来,我们介绍云函数和小程序登录态如何无缝结合,以及如何在云函数端获取小程序用户信息(openid 和 appid)。


获取小程序用户信息

云开发的云函数的独特优势在于与微信登录鉴权的无缝整合。当小程序端调用云函数时,云函数的传入参数中会被注入小程序端用户的 openid,开发者无需校验 openid 的正确性,因为微信已经完成了这部分鉴权,开发者可以直接使用该 openid。与 openid 一起同时注入云函数的还有小程序的 appid。

从小程序端调用云函数时,开发者可以在云函数内使用 wx-server-sdk 提供的 getWXContext 方法获取到每次调用的上下文(appid、openid等),无需维护复杂的鉴权机制,即可获取天然可信任的用户登录态(openid)。可以写这么一个云函数进行测试:

// index.js
const cloud = require('wx-server-sdk')
exports.main = (event, context) => {
  // 这里获取到的 openId、 appId 和 unionId 是可信的,注意 unionId 仅在满足 unionId 获取条件时返回
  let { OPENID, APPID, UNIONID } = cloud.getWXContext() 

  return {
    OPENID,
    APPID,
    UNIONID,
  }
}

假设云函数命名为 test,上传并部署该云函数后,可在小程序中测试调用:

wx.cloud.callFunction({
  name: 'test',
  complete: res => {
    console.log('callFunction test result: ', res)
  }
})

会在调试器看到输出的 res 为如下结构的对象:

{
  "APPID": "xxx",
  "OPENID": "yyy",
  "UNIONID": "zzz", // 仅在满足 unionId 获取条件时返回
}

接下来,我们一起看看如果在云函数中需要进行一段异步操作再返回的时候该如何处理。


异步返回结果

经常,我们需要在云函数中处理一些异步操作,在异步操作完成后再返回结果给到调用方。此时我们可以通过在云函数中返回一个 Promise 的方法来完成。

一个最简的 setTimeout 示例:

// index.js
exports.main = async (event, context) => {
  return new Promise((resolve, reject) => {
    // 在 3 秒后返回结果给调用方(小程序 / 其他云函数)
    setTimeout(() => {
      resolve(event.a + event.b)
    }, 3000)
  })
}

假设云函数名字为 test,上传部署该云函数后,我们可以在小程序端测试调用:

// 在小程序代码中:
wx.cloud.callFunction({
  name: 'test',
  data: {
    a: 1,
    b: 2,
  },
  complete: res => {
    console.log('callFunction test result: ', res)
  },
})

此时应该看到调试器输出:

callFunction test result: 3

使用 npm

在云函数中我们可以引入第三方依赖来帮助我们更快的开发。云函数的运行环境是 Node.js,因此我们可以使用 npm 安装第三方依赖。比如除了使用 Node.js 提供的原生 http 接口在云函数中发起网络请求,我们还可以使用一个流行的 Node.js 网络请求库 request 来更便捷的发起网络请求。

注意,现在上传云函数时不会在云端自动安装依赖,需要开发者在本地安装好依赖后一起打包上传。

接下来,我们一起了解下官方提供的云函数端 SDK: wx-server-sdk。


在云函数中使用 wx-server-sdk

云函数属于管理端,在云函数中运行的代码拥有不受限的数据库读写权限和云文件读写权限。需特别注意,云函数运行环境即是管理端,与云函数中的传入的 openId 对应的微信用户是否是小程序的管理员 / 开发者无关。

云函数中使用 wx-server-sdk 需在对应云函数目录下安装 wx-server-sdk 依赖,在创建云函数时会在云函数目录下默认新建一个 package.json 并提示用户是否立即本地安装依赖。请注意云函数的运行环境是 Node.js,因此在本地安装依赖时务必保证已安装 Node.js,同时 node 和 npm 都在环境变量中。如不本地安装依赖,可以用命令行在该目录下运行:

npm install --save wx-server-sdk@latest

在云函数中调用其他 API 前,同小程序端一样,也需要执行一次初始化方法:

const cloud = require('wx-server-sdk')
// 默认配置
cloud.init()
// 或者传入自定义配置
cloud.init({
  env: 'some-env-id'
})

wx-server-sdk 与小程序端的云 API 以同样的风格提供了数据库、存储和云函数的 API。下面提供几个简单的操作数据库、存储和云函数的示例:

云函数中调用数据库

假设在数据库中已有一个 todos 集合,我们可以如下方式取得 todos 集合的数据:

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
exports.main = async (event, context) => {
  // collection 上的 get 方法会返回一个 Promise,因此云函数会在数据库异步取完数据后返回结果
  return db.collection('todos').get()
}

云函数中调用存储

假设我们要上传在云函数目录中包含的一个图片文件(demo.jpg):

const cloud = require('wx-server-sdk')
const fs = require('fs')
const path = require('path')

exports.main = async (event, context) => {
  const fileStream = fs.createReadStream(path.join(__dirname, 'demo.jpg'))
  return await cloud.uploadFile({
    cloudPath: 'demo.jpg',
    fileContent: fileStream,
  })
}
在云函数中,__dirname 的值是云端云函数代码所在目录

云函数中调用其他云函数

假设我们要在云函数中调用另一个云函数 sum 并返回 sum 所返回的结果:

const cloud = require('wx-server-sdk')

exports.main = async (event, context) => {
  return await cloud.callFunction({
    name: 'sum',
    data: {
      x: 1,
      y: 2,
    }
  })
}

更详细的 wx-server-sdk 文档可参见服务端 API 文档。

接下来,我们一起了解下云函数的运行机制。


运行机制

运行环境

云函数运行在云端 Linux 环境1中,一个云函数在处理并发请求的时候会创建多个云函数实例,每个云函数实例之间相互隔离,没有公用的内存或硬盘空间。云函数实例的创建、管理、销毁等操作由平台自动完成。每个云函数实例都在 /tmp 目录下提供了一块 512MB 的临时磁盘空间用于处理单次云函数执行过程中的临时文件读写需求,需特别注意的是,这块临时磁盘空间在函数执行完毕后可能被销毁,不应依赖和假设在磁盘空间存储的临时文件会一直存在。如果需要持久化的存储,请使用云存储功能。

无状态函数

云函数应是无状态的,幂等的,即一次云函数的执行不依赖上一次云函数执行过程中在运行环境中残留的信息。

为了保证负载均衡,云函数平台会根据当前负载情况控制云函数实例的数量,并且会在一些情况下重用云函数实例,这使得连续两次云函数调用如果都由同一个云函数实例运行,那么两者会共享同一个临时磁盘空间,但因为云函数实例随时可能被销毁,并且连续的请求不一定会落在同一个实例,因此云函数不应依赖之前云函数调用中在临时磁盘空间遗留的数据。总的原则即是云函数代码应是无状态的。

事件模型

云函数的调用采用事件触发模型,小程序端的每一次调用即触发了一次云函数调用事件,云函数平台会新建或复用已有的云函数实例来处理这次调用。同理,因为云函数间也可以相互调用,因此云函数间相互调用也是触发了一次调用事件。

自动扩缩容

开发者无需关心云函数扩容和缩容的问题,平台会根据负载自动进行扩缩容。

Footnotes

  1. 当前运行环境是在 CentOS 7.2 中,特别注意编写代码不应依赖特定的操作系统或特定的操作系统版本号,运行环境可能会发生变化,代码应尽量与平台无关

注意事项 & FAQ

临时存储空间

云函数的运行环境中在 /tmp 目录下提供了一块 512MB 的临时磁盘空间,用于处理单次云函数执行过程中的临时文件读写需求,需特别注意的是,这块临时磁盘空间在函数执行完毕后可能被销毁,不应依赖和假设在磁盘空间存储的临时文件会一直存在。如果需要持久化的存储,请使用云存储功能。

用户代码目录:__dirname

在云函数执行过程中,通过 __dirname 可获取当前云函数的根目录,如果有随云函数打包上传的资源文件,可以通过 __dirname 加相对路径引用获取。

Node.js native 依赖

如果有使用到平台相关的 native 依赖,即依赖需要在相应平台下编译(Windows / macOS / Linux ...)的,务必注意在 Linux 平台(CentOS 7 最佳)下编译后再上传,否则可能出现环境兼容性问题。


在开发者工具中管理云函数

配置云函数本地目录

在项目根目录中可以使用 project.config.json 文件,在其中定义 cloudfunctionRoot 字段,指定本地已存在的目录作为云函数的本地根目录。

云函数操作

在云函数根目录或者云函数目录上,通过鼠标右键,我们可以唤出右键菜单,完成以下操作

  1. 查看当前环境
  2. 切换环境
  3. 新建 Node.js 云函数
  4. 下载线上环境的云函数列表
  5. 下载线上环境的云函数代码并覆盖本地
  6. 对比本地代码和线上环境的代码
  7. 上传并部署云函数到线上环境

查看和切换环境

在云函数根目录上右键,在右键菜单中,可以查看当前对应的环境,同时可以切换环境,之后的所有右键菜单都是在这个环境下进行操作

新建 Node.js 云函数

在云函数根目录上右键,在右键菜单中,可以选择创建一个新的 Node.js 云函数,开发者工具在本地创建出以下目录和文件,同时在线上环境中创建出对应的云函数:

  • 云函数目录:以云函数名字命名的目录,存放该云函数的所有代码
  • index.js:云函数入口文件,云函数被调用时实际执行的入口函数是 index.js 中导出的 main 方法
  • package.json:npm 包定义文件,其中默认定义了最新 wx-server-sdk 依赖

在创建成功后,工具会提示是否为该云函数立即安装本地依赖即 wx-server-sdk,如是,则工具会开启终端执行 npm install


下载云函数列表

在云函数根目录上右键,在右键菜单中,我们可以将线上环境中的云函数列表同步到本地,开发者工具会根据云函数的名字,在本地中创建出对应的云函数目录

下载云函数

在一个云函数目录上右键可以在菜单中选择下载该云函数,云函数代码会被下载到指定目录。

上传并部署

在云函数目录上右键,在右键菜单中,我们可以将云函数整体打包上传并部署到线上环境中

更多设置

我们通过右键菜单的 “更多设置” 可以进入云函数的沉浸式交互场景,在这个场景里可以完成以上所有的云函数操作,在云目录上按 ctrl 可以进行多选批量操作

接下来,我们一起看看如何在开发云函数时进行测试、查看日志、以及查看监控。


测试、日志与监控

测试

云开发提供了云函数测试功能,可以方便地调试你的代码。在控制台的对应云函数的管理面板中,点击 “测试” 按钮即可打开测试弹窗。

测试弹窗

点击“提交方法”下拉菜单可以选择测试函数的模板方法,当前只支持Hello World 事件模板。模板在测试时作为 event 参数传递给函数。在“测试参数”的编辑器中输入想测试的参数后,点击“执行”按钮即可运行代码。执行完毕后将在“运行测试”栏显示运行结果。

除了可视化的云函数测试功能,我们还提供命令行工具 scf-cli, 助你在本地快速调试。

日志

在这里可以查看云函数的调用日志,方便开发者对开发调试。

监控

在这里可以查看云函数的调用次数、运行时间、错误次数。并支持将这些数据导出。


分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)