"NodeJS" (外部计算系统)
更多信息
- 支持 Node.js 版本 7.10.1 以及更高版本.
- Node.js 是一个内置于 Chrome 的 V8 JavaScript 引擎的 JavaScript 运行时.
- 要配置 Node.js 以便用于 Wolfram 语言中,请遵循为 ExternalEvaluate 配置 NodeJS 工作流程的说明.
ExternalEvaluate 用法
- ExternalEvaluate["NodeJS",code] 在 Node.js REPL 中执行代码字符串并以 Wolfram 语言表达式的方式返回结果.
- ExternalEvaluate["NodeJS""String",code] 在 Node.js REPL 中执行代码字符串,不诠释结果.
- ExternalEvaluate["NodeJS""type",code] 中 "type" 可取的设置包括:
-
"Expression" 尝试转换为 Wolfram 语言表达式 "String" 给出外部运算器输出的原始字符串 "ExternalObject" 用 ExternalObject 的形式返回结果
数据类型
- 支持以下 JavaScript 内置类型:
-
Boolean True | False 布尔 True/False 值 Number Integer,Real 整数或实数 String String 字符的字符串 Array List 对象列表 Map Association 关联数组 Undefined Null 未定义的值 - 对于任何不支持的 NodeJS 类型,如果是函数,返回 ExternalFunction;任何其他不支持的 NodeJS 类型则返回 ExternalObject.
支持的外部运算
- ExternalOperation["Eval","code"] 表示 "code" 的外部运算.
- ExternalOperation["Eval","code",assoc] 表示 "code" 的外部运算,参数由 assoc 给出.
- ExternalOperation["Call",func,arg1,arg2,…] 调用函数 func,给定参数为 arg1、arg2、….
- ExternalOperation["GetAttribute",obj,"attr"] 获取 obj 的属性 "attr".
- ExternalOperation["SetAttribute",obj,"attr",val] 将 obj 的属性 "attr" 设为给定值 val.
- ExternalOperation["Cast",obj,"type"]将 obj 强制设为给定的 "type".
范例
打开所有单元 关闭所有单元基本范例 (2)
ExternalEvaluate["NodeJS", "2+2"]ExternalEvaluate["NodeJS", "[1,2,3,4]"]使用 File 包装器来执行文件中的代码:
path = Export[CreateFile[], "[1, 2, 'hello']", "String"]ExternalEvaluate["NodeJS", File[path]]使用 CloudDeploy 部署代码,然后直接从 CloudObject 中运行代码:
cobj = CloudExport["[1, 2, 'hello']", "String"]ExternalEvaluate["NodeJS", cobj]使用一个 URL 包装器来直接运行在线托管的代码:
functions = URL["https://exampledata.wolfram.com/script.js"]ExternalEvaluate["NodeJS", {functions, "cube(3)"}]范围 (27)
session = StartExternalSession["NodeJS"]ExternalEvaluate[session, "true || false"]ExternalEvaluate[session, "'hello'+' '+'world'"]使用 NodeJS 创建 ExternalFunction:
incr = ExternalFunction[session, "x => x + 1"]incr[3]DeleteObject[session]会话选项 (8)
"ReturnType" (3)
对于 NodeJS,默认返回类型为 "Expression":
ExternalEvaluate["NodeJS", "2+2"] === ExternalEvaluate["NodeJS" -> "Expression", "2+2"]数字、字符串、列表和关联会自动导入 "Expression" 返回类型:
ExternalEvaluate["NodeJS", "[2, 3]"]使用 JSON,返回类型为 "String" 会返回字符串:
ExternalEvaluate["NodeJS" -> "String", "[1, 2, 'א']"]StringQ[%]"Evaluator" (1)
"SessionProlog" (1)
"SessionEpilog" (1)
"Prolog" (1)
命令选项 (10)
"Command" (4)
ExternalEvaluate["NodeJS", "[1, 2, 3]"]ExternalEvaluate["NodeJS", <|"Command" -> "[1, 2, 3]"|>]使用 File 包装器来运行文件中的代码:
ExternalEvaluate["NodeJS", {
<|"Command" -> File["ExampleData/powers.js"]|>,
<|"Command" -> "square(3)"|>,
<|"Command" -> "cube(3)"|>
}]ExternalEvaluate["NodeJS", {
File["ExampleData/powers.js"],
"square(3)",
"cube(3)"
}]使用 URL 包装器来直接运行在线托管的代码:
ExternalEvaluate["NodeJS", {
<|"Command" -> URL["https://exampledata.wolfram.com/script.js"]|>,
<|"Command" -> "cube(3)"|>
}]ExternalEvaluate["NodeJS", {
URL["https://exampledata.wolfram.com/script.js"],
"cube(3)"
}]把代码放在 CloudObject 中:
cloudObj = CloudExport["console.log('Hello World!')", "Text", CloudObject["hello-world-js"]]ExternalEvaluate["NodeJS", <|"Command" -> cloudObj|>]ExternalEvaluate["NodeJS", cloudObj]"ReturnType" (1)
"Arguments" (2)
ExternalEvaluate[
"NodeJS",
<|"Command" -> "(a, b) => a + b", "Arguments" -> {1, 2}|>
]ExternalEvaluate[
"NodeJS",
<|"Command" -> "a => a", "Arguments" -> 1|>
]如果你需要传递列表作为第一个参数,则该列表需要明确地包装在一个额外的列表中:
ExternalEvaluate[
"NodeJS",
{
<|"Command" -> "a => a", "Arguments" -> 1|>,
<|"Command" -> "a => a", "Arguments" -> {1}|>,
<|"Command" -> "a => a", "Arguments" -> {{1}}|>
}
]你可以在 "Command" 中命名一个函数,然后用 "Arguments" 直接调用它:
ExternalEvaluate[
"NodeJS",
<|"Command" -> "parseInt", "Arguments" -> "123"|>
]同样的结果可以通过使用 Rule 来归档:
ExternalEvaluate[
"NodeJS",
"parseInt" -> "123"
]另一种方法是定义一个 ExternalFunction:
session = StartExternalSession["NodeJS"]function = ExternalFunction[session, "parseInt"]function["123"]DeleteObject[session]"Constants" (1)
"TemplateArguments" (2)
当运行命令时,你可以内联一个 TemplateExpression:
x = RandomReal[]
ExternalEvaluate["NodeJS", "1 + <* x *>"]你可以使用 "TemplateArguments" 对 TemplateSlot 进行填充:
ExternalEvaluate[
"NodeJS",
<|"Command" -> "2 + ``", "TemplateArguments" -> 1|>
]如果你需要传递列表作为第一个参数,请将该列表包装在一个额外的列表中:
ExternalEvaluate[
"NodeJS",
{
<|"Command" -> "JSON.stringify(``)", "TemplateArguments" -> 1|>,
<|"Command" -> "JSON.stringify(``)", "TemplateArguments" -> {1}|>,
<|"Command" -> "JSON.stringify(``)", "TemplateArguments" -> {{1, 2}}|>
}
]你可以为模板槽命名,并使用 Association 来向模板传递命名的参数:
ExternalEvaluate[
"Python",
<|"Command" -> "(`x` - `y` + `z`)", "TemplateArguments" -> <|"x" -> 10, "y" -> 3, "z" -> 2|>|>
]外部运算 (8)
"Eval" (1)
运行表示 NodeJS 中任意代码运算的 ExternalOperation:
ExternalEvaluate["NodeJS", ExternalOperation["Eval", "2+2"]]ExternalEvaluate["NodeJS", ExternalOperation["Eval", "a + b", <|"a" -> 2, "b" -> 3|>]]"Call" (3)
定义一个在 NodeJS 中创建函数的 ExternalOperation:
op = ExternalOperation["Eval", "Math.max"]通过运行 ExternalOperation "Call" 调用函数:
call = ExternalOperation["Call", op, 1, 2]用 ExternalEvaluate 执行运算:
ExternalEvaluate["NodeJS", call]"Call" 运算的任何参数都可以是 ExternalOperation:
ExternalEvaluate["NodeJS", ExternalOperation["Call", op, 1, ExternalOperation["Eval", "2+2"]]]还可以通过执行以下操作直接在 ExternalEvaluate 中传递参数:
ExternalEvaluate["NodeJS", op -> {1, 2}]ExternalEvaluate["NodeJS", "Math.max(1, 2)"]创建 NodeJS 函数 max 的 ExternalFunction:
max = ExternalFunction["NodeJS", "Math.max"]ExternalEvaluate["NodeJS", ExternalOperation["Call", max, 1, 2]]ExternalEvaluate["NodeJS", max -> {1, 2}]创建 NodeJS 函数的 ExternalFunction:
session = StartExternalSession["NodeJS"]max = ExternalEvaluate[session, <|"Command" -> "Math.max", "ReturnType" -> "ExternalObject"|>]ExternalEvaluate[session, ExternalOperation["Call", max, 1, 2]]ExternalEvaluate[session, max -> {1, 2}]或使用 ExternalObject 子值:
ExternalObject[max][ExternalOperation["Call", 1, 2]]DeleteObject[session]"GetAttribute" (2)
session = StartExternalSession["NodeJS"];返回一个 "Math" 对象的 ExternalObject:
math = ExternalEvaluate[session, <|"Command" -> "Math", "ReturnType" -> "ExternalObject"|>]ExternalEvaluate[session, ExternalOperation["GetAttribute", math, "max"]]ExternalEvaluate[session, ExternalOperation["GetAttribute", math, "max"] -> {1, 2}]ExternalEvaluate[session, "Math.max(1, 2)"]DeleteObject[session]创建表示 "Math" 对象的 ExternalObject:
session = StartExternalSession["NodeJS"]math = ExternalEvaluate[session, <|"Command" -> "Math", "ReturnType" -> "ExternalObject"|>]用 ExternalOperation 获取函数:
math[ExternalOperation["GetAttribute", "max"]]对于大多数运算器,"GetAttribute" 是默认运算,可以省略 ExternalOperation:
math["max"]math["max", ExternalOperation["Call", 1, 2]]math["max" -> {1, 2}]DeleteObject[session]"SetAttribute" (1)
session = StartExternalSession["NodeJS"];在 NodeJS 中创建一个对象;创建单个对象时,必须用括号括起来:
obj = ExternalEvaluate[session, <|"Command" -> "({})", "ReturnType" -> "ExternalObject"|>]ExternalEvaluate[session, ExternalOperation["SetAttribute", obj, "b", 6]]ExternalEvaluate[session, ExternalOperation["GetAttribute", obj, "b"]]ExternalEvaluate[session, "obj = {}; obj.b = 6"]DeleteObject[session]"Cast" (1)
创建表示数组的 ExternalObject:
session = StartExternalSession["NodeJS"];now = ExternalEvaluate[session, <|"Command" -> "[1, 2, 3]", "ReturnType" -> "ExternalObject"|>]用 "Expression" 以 Wolfram 语言表达式的形式返回对象:
ExternalEvaluate[session, ExternalOperation["Cast", now, "Expression"]]也可以在 ExternalObject 子值中运行 Cast 运算:
now[ExternalOperation["Cast", "Expression"]]符号 Expression 是完成相同运算的更简便的方式:
now[Expression]now[ExternalOperation["Cast", "String"]]符号 String 是完成相同运算的更简便的方式:
now[String]用 ExternalObject 返回对象:
now[ExternalOperation["Cast", "ExternalObject"]]符号 ExternalObject 是完成相同运算的更简便的方式:
now[ExternalObject]在 ExternalEvaluate 中使用 "ReturnType" 可以得到同样的结果:
ExternalEvaluate[session, <|"Command" -> now, "ReturnType" -> "String"|>]DeleteObject[session]应用 (2)
在 NodeJS 中定义 Range 函数:
range[n1_, n2_, step_ : 1] :=
ExternalEvaluate["NodeJS", <|
"Command" -> "(n1, n2, step=1) => {
if (! n2 && ! n2 == 0) {
return range(0,n1-1,step)
}
const arr=[];
for (let i=n1;i<=n2;i+=step) {
arr.push(i)
}
return arr
}",
"Arguments" -> {n1, n2, step}
|>]range[1, 10]使用 prettier 重新格式化一个 JavaScript 代码字符串:
reformatJavascriptCode[code_] :=
Last @ ExternalEvaluate["NodeJS", {
"const prettier = require('prettier')",
<|
"Command" -> "prettier.format",
"Arguments" -> code
|>
}]reformatJavascriptCode["foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne());"]相关指南
-
▪
- 外部已诠释的语言接口 ▪
- 外部语言接口
相关的工作流程
- 为 ExternalEvaluate 配置 NodeJS
历史
2018年引入 (11.3)