📜 ⬆️ ⬇️

Our cloud-based JS is now ES2017, and this reduces the code by several times.


Contrary to popular belief, Voximplant cloud does not use Node.js to perform client JavaScript code in parallel with voice and video calls. Each of our servers simultaneously manages hundreds of calls: switching voice and video streams between calls, recording, voice recognition, synthesis, HTTP requests to external servers — the whole story. Node.js is designed to work alone. A few hundred isolated instances are not about her. They will distort for memory, resources and everything will end very sadly. Therefore, we have a highly isolated and resource-constrained sandbox that does not allow client-side JavaScript code to disrupt entire servers in one small session. Asterisk is also not used for similar reasons.

Until recently, we supported ES5 syntax. A typical communication scenario is a few hundred, or a maximum, thousand lines of code. Difficult things customers still put on their own backend, and if you need a modern syntax, you can always use the transpiler and automatically ship the generated JavaScript using Continuous Integration .

But 2017 obliges, and clients love and use the Web editor and debugger to quickly create the right solutions. Therefore, we wrote down the support for ES2017 (not from scratch, of course, but with ready-made components) and redid the training materials in a modern way. Under the cut, I want to show how shorter and clearer the code becomes if we use modern JavaScript notation. The difference is impressive.

async and await


Since our API has returned promises for quite some time, where it is possible, then the then chain with parameter passing turns into well readable linear code:
')
//
VoxEngine.addEventListener(AppEvents.Started, async function(e) {
var text1, text2, text3;
Net.httpRequestAsync("www.ru")
.then(function(e) {
text1 = e.text;
return Net.httpRequestAsync("ya.ru");
})
.then(function(e) {
text2 = e.text;
return Net.httpRequestAsync("mail.ru");
})
.then(function(e) {
text3 = e.text
doSomething(text1, text2, text3);
VoxEngine.terminate();
}
});
//
VoxEngine.addEventListener(AppEvents.Started, async e => {
const {text: text1} = await Net.httpRequestAsync("www.ru");
const {text: text2} = await Net.httpRequestAsync("ya.ru");
const {text: text3} = await Net.httpRequestAsync("mail.ru");
doSomething(text1, text2, text3);
VoxEngine.terminate();
});
view raw async-await-example.js hosted with ❤ by GitHub

arrow functions and destructuring


Just shorten the code. Especially destructuring, which removes temporary identifiers and leaves only what we need:

// before
call.addEventListener(CallEvents.MessageReceived, function(e) {
var headers = e.headers;
var text = e.text;
doSomething(text, headers);
});
// after
call.addEventListener(CallEvents.MessageReceived, e => {
const {headers, text} = e;
doSomething(text, headers);
});

let and const


It is good when there is a linter, autobild, autotest and auto-warm. But in reality, you often need to quickly go into the script and change something from the web editor. The new let and const allow you to write code that will protect the developer from "childish" errors:

// before
VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) {
var callIn = e.call;
var callIn = VoxEngine.callPSTN("+71234567890"); // bug
callIn.addEventListener(CallEvents.Connected, function(e) {
VoxEngine.sendMediaBetween(callIn, callOut);
});
});
// after
VoxEngine.addEventListener(AppEvents.CallAlerting, e => {
const callIn = e.call;
const callIn = VoxEngine.callPSTN("+71234567890"); // bug found!
callIn.addEventListener(CallEvents.Connected, e => {
VoxEngine.sendMediaBetween(callIn, callOut);
});
});
view raw let-const-example.js hosted with ❤ by GitHub

interpolation string literals


They make the code readable and protect against a lot of children's errors in the absence of the toolchain. Yes, we know that developing on JS without a toolchain is a moveton. But when the service has thousands of clients and many have their main business in no way connected with programming, I want to protect them already at the stage of examples and first experiments. One of the “chips” of Voximplant is that the company can take on its full-time web developer, it’s not very tough, and in a few hours it can easily assemble the necessary telephone automation from the “Lego cubes”. I really want the cubes to not try to explode in his hands:

// before
call.say("" + name + ", " + order + " ");
// after. Watch the spaces!
call.say(` ${name}, ${order} `);

Of-cycles, classes, helpers and other little things


Most of the scenarios for our platform are fairly “lightweight”: requests to the backend, routing the call where necessary, and displaying in CRM, which is not necessary, automatic calls with proof of purchase or delivery, choosing the right counterparty under a number of conditions and the like. But it's always great to do without our own backend in general and make our cloud do all the work not only with communications, but also with the business logic of these communications. We generally do not mind, as long as the script fits within the boundaries of the sandbox and does not try to bite off too many server resources. Native support for all ES2017 syntax sugar allows you to quickly add logic to scripts without having to set up a compiler from any TypeScript, tests and deploy. Then all this, of course, does not hurt - but the ability to do a complex thing here and now in the online editor with a minimum of lines of code helps a lot.

Source: https://habr.com/ru/post/340188/


All Articles