Appearance
脚本引擎
介绍
脚本引擎分两个版本,js1.0
, js2.0
,通过系统参数:bingo.script.use.js2.0
来进行切换。两个版本脚本引擎差异如下:
语言特性支持
特性项 | js1.0 | js2.0 | 说明 |
---|---|---|---|
ES标准支持情况 | ES5.1, 部分ES6特性 | ES2022 | |
模块支持情况 | commonjs | es module/commonjs | 通过系统参数bingo.js2.script.module 控制 |
异步支持(Promise/async/await) | N | Y | |
setTimeout, clearTimeout | N | Y | |
ES6 class support | Y | Y | |
Proxy | Y | Y | |
Symbol | Y | Y | |
Map, Set, WeakMap, WeakSet | Y | Y | |
Typed Arrays | Y | Y | |
for-of | Y | Y | |
Reflect | Y | Y | |
Block-scoped declarations (let and const) | Y | Y | |
Optional catch binding | Y | Y | |
Destructuring assignments | Y | Y | |
Default function parameters | Y | Y | |
Spread and rest properties | Y | Y | |
Arrow functions | Y | Y | |
Template literals | Y | Y | |
Optional chaining | Y | Y | |
** Operator | Y | Y | |
Nullish Coalescing Operator | Y | Y | |
generators | Y | Y | |
String.prototype.replaceAll | Y | Y | |
js1.0/js2.0均不兼容
npm
生态。
性能差异
js2.0
性能远远优于js1.0
, 大部分场景下,性能提升了100%~1000%
, 如JSON.parse
提升了800%
, JSON.stringify
提升了500%
。
js2.0新增加API
因为js2.0
支持异步,所以新增加部分异步api
:
- setTimeout
- clearTimeout
- db.sql.executeAsync
ts
import * as db from 'db';
function bad() {
let p = db.sql().executeAsync("select * from m__wasm__cst limit 1", { dynamic: false });
p.then((value) => {
console.log(value);
}).catch((reason) => {
console.log("execption = ", reason);
});
}
function ok() {
let p = db.sql().executeAsync("select * from m__wasm__cst limit 1", { dynamic: true });
p.then((value) => {
console.log("affected rows = ", value.AffectedRows);
}).catch((reason) => {
console.log("execption = ", reason);
});
}
console.log("hello 1");
setTimeout(ok, "1000");
console.log("hello 2");
setTimeout(bad, "100");
console.log("hello 3");
输出:
bash
0703 15:27:00.626|debug|vm[1]>>> hello 1 (m__obs:18)
0703 15:27:00.626|debug|vm[1]>>> hello 2 (m__obs:20)
0703 15:27:00.626|debug|vm[1]>>> hello 3 (m__obs:22)
0703 15:27:01.631|debug|vm[1]>>> affected rows = 1 (m__obs:13)
0703 15:27:01.631|debug|vm[1]>>> execption = Error
{
message: "object m__wasm__cst is used but not decorated with @useObject, please decorate it first."
} (m__obs:7)
- http.client.requestAsync
ts
import * as http from 'http';
import * as context from 'context';
const option: http.ClientOption = {
baseUrl: context.getHost() + "/u-route/baas/"
}
const headers = {
"access-token": context.getToken(),
"content-type": "application/json",
};
const client = http.newClient(option);
let p = client.requestAsync(http.Method.GET, "script/v1.0/declaration", { headers: headers });
p.then((resp) => {
console.log(`resp length is `, len(resp.body.result));
}).catch((reason) => {
console.log(`error is `, reason);
});
console.log("hello, here");
输出:
bash
0712 16:46:57.832|debug|vm[68]>>> hello, here (m__httpdemo:19)
0712 16:46:57.832|debug|vm[68]>>> resp length is 2 (m__httpdemo:15)
动态加载模块
commonjs的require函数,esmodule的import函数。
commonjs:
ts
const res = require('./m__util');
res.sayHello('common js dynamic import');
esmodule:
ts
import('./m__util').then((res) => {
res.sayHello("es module dynamic import");
});
兼容性差异
部分AppCube封装api有些差异:
Decimal类型Exponent方法在某些场景计算结果不同
ts
import * as decimal from 'decimal';
let d1 = decimal.newFromString('-123.4567');
let d2 = decimal.newFromString('-321.231');
let avg = decimal.avg(d1, d2);
console.log("avg : ", avg);
console.log("avg exponent : ", avg.Exponent());
js1.0
输出结果
bash
617 19:38:03.685|debug|vm[12]>>> avg : -222.34385 (m__avgdecimal.ts:6:12(36))
0617 19:38:03.685|debug|vm[12]>>> avg exponent : -16 (m__avgdecimal.ts:7:12(44))
js2.0
输出结果:
bash
0617 19:35:29.125|debug|vm[11]>>> avg : -222.34385 (m__avgdecimal:5)
0617 19:35:29.125|debug|vm[11]>>> avg exponent : -5 (m__avgdecimal:6)
从输出结果来看,js2.0
输出结果更加符合我们的直觉。