Appearance
Script Engine
Introduction
The script engine has two versions: js1.0 and js2.0. The script engine can be switched through the system parameter bingo.script.use.js2.0 . The differences between the script engines of the two versions are as follows:
Language feature support
| Feature | js1.0 | js2.0 | Description |
|---|---|---|---|
| Support for ES standards | ES5.1, partial support for ES6+ | ES2022 | |
| Module support | commonjs | es module/commonjs | switch module mode by bingo.js2.script.module system parameter. |
| Asynchronous Support (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 | |
both js1.0 and js2.0 are not compatible with the'npm' ecosystem.
Performance Differences
The performance of js2.0 is much better than that of js1.0. In most scenarios, the performance is improved by 100% to 1000%. For example, JSON.parse is improved by 800%, and JSON.stringify is improved by 500%.
New APIs in JS 2.0
Because js2.0 supports asynchronization, some asynchronization api are added:
- 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");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");output:
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)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");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");output:
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)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)dynamicly import module
commonjs uses the require function, and esmoudle uses the import function.
commonjs:
ts
const res = require('./m__util');
res.sayHello('common js dynamic import');const res = require('./m__util');
res.sayHello('common js dynamic import');esmodule:
ts
import('./m__util').then((res) => {
res.sayHello("es module dynamic import");
});import('./m__util').then((res) => {
res.sayHello("es module dynamic import");
});Compatibility Differences
Some AppCube APIs are different:
The Exponent method of the Decimal type has different results in some scenarios.
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());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 Output Result
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))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))The output of js2.0 is as follows:
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)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)From the output, the js2.0 output is more in line with our intuition.