CloudScript 中的 ES6 功能

CloudScript 运行时环境支持大多数现代 ECMAScript 6 功能。 虽然这些功能中的大多数都是语法技巧,但你可以使用它们来改进和清理 CloudScript 代码。

有关 ES6 功能的完整概述,请参阅此速查表

本教程介绍您可以在 CloudScript 中使用的一些技巧。

注意

某些功能需要严格模式。 通过将以下代码放在 CloudScript 文件的第一行来启用此模式:use strict;

字符串内插

在为玩家编写消息时,您可能希望使用多行内插字符串。 使用重音符 创建内插字符串。 然后,可以使用 ${ variable } 语法将数据直接插入到字符串中。

这允许您避免字符串串接,并提高代码可读性。

注意

重音符字符串是逐字字符串,可以包含多行。 这意味着您必须密切注意所有缩进,因为任何多余空格/制表符都将被捕获到字符串中。

function sendPushNotification(playerName, prizeAmount, newLevel) {
    let message = `Congratulations ${playerName}!
You have reached level ${newLevel}.
You get ${prizeAmount} coins for your efforts.`;
    // Use message variable and send push notification
    // ...
}

新方法和箭头函数

ES6 引入了使用箭头运算符 => 定义函数的 语法。 下面显示的代码段演示了某些运算符用法的大致翻译。

// The following snippets:
const add = (a,b) => a+b;

const add = (a,b) => {
    return a+b;
}

// Both translate into something like
function add(a, b) {
    return a+b;
}

此运算符与新的 Array.findIndex 方法相结合,允许您使用以下漂亮、简洁的代码按谓词进行搜索。

const players = [...]; // Suppose this is an array of Player Profiles

// Search by predicate: find item in 'players' that has 'DisplayName' set to 'Bob':
const bobIndex = players.findIndex(p => p.DisplayName === 'Bob');

对象分配

Object.assign 方法允许您使用一组新的属性和方法轻松扩展任何对象。

此方法有很多用法,对于扩展处理程序对象和创建处理程序组特别有用。

let TestHandlers = {
    TestLeaderboards : (args, ctx) => {
        // Test leaderboards code
    },
    TestPrizes : (args, ctx) => {
        // Test prizes code
    }
    // ...
}

let ProductionHandlers = {
    CleanUp : (args, ctx) => {
        // System clean up code
    },
    GrantTournamentAccess : (args, ctx) => {
        // Another useful production code
    }
    // ...
}

// Install both handler groups:
Object.assign(handlers, TestHandlers);
Object.assign(handlers, ProductionHandlers);

// Comment out the group to disable it but keep the relevant code
// Object.assign(handlers, SomeOtherHandlers);

这不仅允许您快速启用和禁用处理程序组,还让您能够对处理程序进行处理并为其包装有用的代码,例如异常处理。

以下代码使用自动异常日志记录对上面的代码段进行了扩展。 我们仅以记录问题为例进行说明(用途并不广泛),但您可以根据自己的喜好对行为进行扩展。

// Handlers installer wraps the handler to catch error
function installHandlers(handlersObject) {
    for (let property in handlersObject) {
        handlersObject[property] = wrapHandler(handlersObject,property)
    }
    Object.assign(handlers, handlersObject);
}

// Utility
function wrapHandler(obj, key) {
    if (obj.hasOwnProperty(key) && typeof obj[key] === 'function') {
        let original = obj[key]; // Take the original function
        return function() { // return a new function that
            try { // Wraps the original invocation with try
                return original.apply(null,arguments); // Do not forget to pass arguments
            } catch (error) { // If error occurs
                log.error(error); // We log it, but you may want to retry / do something else
                throw error; // Rethrow to keep the original behaviour
            }
        }
    } else { // If property is not a function, ignore it
        return obj[key];
    }
}

// Install handler groups:
installHandlers(TestHandlers);
installHandlers(ProductionHandlers);

Getter

可以使用“Getter”封装常用的 API 调用,让其语法更赏心悦目。 请考虑以下 Title Data 状态。

Game Manager - Title Data

以下代码段介绍如何从 TitleData 检索 FooBar 数据,然后以极其简单的方式使用它们。

'use strict'

// Define
let App = {
    get TitleData() {
        // Please, consider limiting the query by defining certain keys that you need
        return server.GetTitleData({}).Data;
    },
}

// Use
handlers.TestFooBar = () => {
    // Client code is clean and does not show the fact of calling any functions / making api request
    var titleData = App.TitleData; // Note that this implementation makes an API call every time it's accessed
    log.debug(titleData.Foo);
    log.debug(titleData.Bar);
}