详解基于 Node.js 的轻量级云函数功能实现

2020-06-17 05:47:02易采站长站整理

// return 'hahha'
// }

有了字符串的函数体,存储就很简单了,直接存在数据库

string
类型的字段里即可。

2、函数执行

url

如果用于前端调用,每个云函数需要有一个对应的 url,以上述声明文件的文件名为云函数的唯一名称的话,可以简单将 url 设计为:


/f/:funcname

构造独立作用域(重点)

在 js 世界里,执行一个字符串类型的函数体,有以下这么一些途径:

eval
函数
new Function

vm
模块

那么要选哪一种呢?让我们回顾云函数的特点:各自独立,互不影响,运行在云端。

关键是将每个云函数放在一个独立的作用域执行,并且没有访问执行环境的权限,因此,最优选择是 nodejs 的

vm
模块。关于该模块的使用,可参考官方文档。

至此,云函数的执行可以分为三步:

从数据库获取函数体
构造

context


// ctx 为 koa 的上下文对象
const sandbox = {
ctx: {
params: ctx.params,
query: ctx.query,
body: ctx.request.body,
userid: ctx.userid,
},
promise: null,
console: console
}
vm.createContext(sandbox);

执行函数得到结果


const code = `func = ${funcBody}; promise = func(ctx);`;
vm.runInContext(code, sandbox);
const data = await sandbox.promise;

NPM社区的

vm2
模块针对
vm
模块的一些安全缺陷做了改进,也可用此模块,思路大抵相同。

3、引用

虽然说原则上云函数应当互相独立,各不相欠,但是为了提高灵活性,我们还是决定支持函数间的相互引用,即可以在某云函数中调用另外一个云函数。

声明

很简单,加个函数名称的数组字段就好:


module.exports = {
method: 'POST',
use: ['func1', 'func2'],
handler: async function (ctx) {
return 'hahha'
}
};

注入

也很简单,根据依赖链把函数都找出来,全部挂载在

ctx
下就好,深度优先或者广度优先都可以。


if (func.use) {
const funcs = {};
const fnames = func.use;
for (let i = 0; i < fnames.length; i++) {