1.8.4 脚本节点编码指导

优质
小牛编辑
125浏览
2023-12-01

脚本节点编码指导

更新时间:2018-03-19 18:11:31

可以在脚本节点中编写node.js代码,目前支持的node.js版本为6.10

约束和限制

1. Date

服务编排最终会运行在阿里云的云产品函数计算(Function Computer)上,函数计算满足国际化需求,使用的是UTC时间,因此在使用Date对象时请注意当前时区和UTC时间的差异。如在东八区(北京时间)使用如下代码

new Date().getHours()

获取到的小时数将比北京时间少8个小时。

2. npm库

不支持随便引入第三方的npm库,目前服务编排支持的npm库将在下文列出。

3. 异步操作

如果在脚本中定义了异步操作,而又想在后面能及时获取到异步操作的结果,则异步操作必须返回一个Promise对象,且在脚本中需将该Promise对象显示地返回,详细见下文示例。

4. 变量

变量必须符合ECMAScript2015在严格模式下变量的命名规范
不能使用以下的关键字命名变量

abstract,
boolean, break, byte,
case, catch, char, class, continue, const,
debugger, default, delete, do, double,
else, enum, export, extends,
false, finally, for, function,
goto,
if, import, implements, in, instanceof, int, interface,
let, long,
native, new, null,
package, private, protected, public,
return,
short, static, super, switch, synchronized,
this, throw, throws, transient, try, typeof,
var, void, volatile,
while, with,
yield

此外,特别注意,请勿在脚本中定义使用包含循环引用的变量

var obj = {};
obj.aaa = obj;

如上变量obj包含循环引用,在脚本中请勿使用。

可获取的变量、函数、npm库

1. msg

msg为编排的上下文,在msg中可以去到数据如下:
msg.payload: 上一个节点的输出
msg.request: 最初的输入
msg.nodes: 每个节点的输入输出,msg.nodes[id]获取到的是已执行节点的输入输出信息。

msg.nodes[id] = {
    id: '',  
    type: '',  
    input: {},  
    output: {}
}

其中id为节点id,type为节点类型,input为节点的输入,output为节点的输出。

2. apiClient

可以使用apiClient调用在平台上开发的服务,包括官方服务、自研服务、市场服务。
示例为

apiClient.post(url, version, params)

该调用会返回一个promise对象。
其中url为服务的url路径,version为服务的版本,params为服务的入参(json格式)。
具体使用示例如下:

const co = require('co');
const url = 'http://xxxxx';
const version = '1.0.0';
const params = {scope: '1'};
const promise = co(function* () {
    var result = yield apiClient.post(url, version, params);
    if(result.code === 200){
        return result.data;
    }

    return result;
});

return promise;

最终必须返回Promise对象。

3. logger

可以使用logger输出日志,这些日志数据可以在调试信息中看到。
使用示例如下:

let data = {id, 123, name: 'lucy'};
logger.info(data);

let name = 'Jack';
logger.info('Hello', name);

logger.info为输出日志的函数调用,参数个数不限。

4. node.js的全局变量

node.js的全局变量都可以在脚本节点中获取到。
node.js自带的内部模块也可以使用,使用前先require引入。

5. 第三方的npm库

名称版本描述文档
co4.6.0控制流https://github.com/tj/co
axios0.17.1HTTP客户端https://github.com/axios/axios
moment2.20.1日期处理https://github.com/moment/moment
lodash4.17.4工具类https://github.com/lodash/lodash
uuid3.2.1UUIDhttps://github.com/kelektiv/node-uuid
gm1.23.1图片处理库https://github.com/aheckmann/gm
opencv6.0.0视觉算法库https://github.com/peterbraden/node-opencv
ali-oss4.11.5OSS SDKhttps://github.com/ali-sdk/ali-oss

| aliyun-sdk | 1.11.2 | Aliyun SDK | https://github.com/aliyun-UED/aliyun-sdk-js |

| @alicloud/fc2 | 2.0.0 | 函数计算SDK | https://github.com/aliyun/fc-nodejs-sdk |

自定义异常

在脚本节点中,可以通过throw抛出自定义异常,示例如下

throw { code: 82430, message: 'self-define exception', localizedMsg: '自定义异常' };

其中code为异常的编码,message为异常的英文定义,localizedMsg为异常的中文定义。
注意:使用throw语句抛出异常后,如果没有显示catch,将导致编排流程的中止。

代码示例

1. 输入输出示例

脚本节点代码示例如下

let input = msg.payload;
let name = msg.payload.name;
let id = msg.payload.id;
let result = 'hello, id is ' + id + ', name is ' + name;

msg.payload = result;

return result;

代码示例如上,说明:

输入

默认从msg.payload中读取入参

输出

1、可以将出参覆盖写入到msg.payload,也可以直接将出参return result
2、这两种方式都可以将脚本的结果输出,这样在下一个节点又可以通过msg.payload拿到当前脚本的输出。
3、如果需要返回的是undefined,则请务必显示地覆盖msg.payload = undefined,直接return undefined不会使得msg.payload被赋值undefined
4、如果不想覆盖之前的msg.payload,则可以指定写到其它属性上,如msg.payload2 = result

异步调用

脚本节点中如果包含异步调用,则必须返回一个Promise对象。

var promise = new Promise(function(reject, resolve){
    doAsync('', function(err, data){
        if(err){
            reject(err)
        }
        resolve(data)
    })
})

return promise

如上所示,异步操作必须返回一个promise对象。

2. co模块使用示例

支持使用co模块,如下

const co = require('co');

var promise = co(function* () {
    var result = yield doAsync();

    return result;
});

return promise;

最终必须将promise返回

3. apiClient使用示例

脚本节点中使用apiClient示例

const co = require('co');
const url = 'http://xxxxx';
const version = '1.0.0';
const params = {scope: '1'};
const promise = co(function* () {
    var result = yield apiClient.post(url, version, params);
    if(result.code === 200){
        return result.data;
    }

    return result;
});

return promise;

最终必须将promise返回。

4. 调用外部服务示例

脚本节点中可以调用第三方服务示例,如高德地图、github的API
1、脚本节点中支持axios,因此可以使用axios来调用外部服务。
get请求示例

const axios = require('axios')
const co = require('co')

const promise = co(function* (){
    const url = 'http://localhost:8080/greeting/test1?name=lucy'

    let result = yield axios.get(url)

    return result.data
})

上述代码中,请勿将axios.get的结果result直接返回,该result包含了循环引用,目前在整个编排过程中不支持包含循环引用的变量。
post请求示例

const axios = require('axios')
const co = require('co')

const promise = co(function* (){
    const url = 'http://localhost:8080/greeting/test2'
    const data = {
        id: 123,
        content: 'hello how are you'
    }

    let result = yield axios.post(url, data)
    return result.data
})

同样,请勿将result直接返回,请返回result.data

2、也可以使用node.js原生的http/https模块来调用,示例如下:

const https = require('https');
const promise = new Promise((resolve, reject) => {
    const https = require('https');

    const options = {
        hostname: 'api.github.com',
        port: 443,
        path: '/rate_limit',
        method: 'GET',
        headers: {
            'User-Agent': 'Mozilla/5.0'
        }
    };

    const req = https.request(options, (res) => {

        res.setEncoding('utf8');
        res.on('data', (chunk) => {
            console.log(chunk);
            resolve(JSON.parse(chunk));
        });
        res.on('end', () => {
            console.log('No more data in response.');
        });
    });

    req.on('error', (e) => {
        console.error(`problem with request: ${e.message}`);
        reject(e);
    });

    req.end();
});

return promise;