Zone 底座:原子函数
Methods
(static) assign(target, source, mode) → {Object}
「标准」Ux.assign
三种模式的拷贝函数,增强原始的Object.assign
函数。
- mode = 0 :直接覆盖,内部调用
Object.assign
方法。 - mode = 1 :深度覆盖,不直接覆盖子对象,递归往下,发现同键数据后直接覆盖数据。
- mode = 2 :深度追加,不直接覆盖子对象,递归往下,同键不存在则追加,出现重复建则直接跳过。
// mode = 0(默认模式)
const target = {
name: "mode"
};
const source = {
email: "lang.yu@hpe.com"
};
// 等价于 Object.assign(target,source);
const combine = Ux.assign(target,source);
// mode = 1 和 mode = 2 的模式则参考实际使用。
实际上mode为1或2的场景在很多实战场景中有所使用,这两种模式不会直接覆盖子对象(包括嵌套对象),而是通过比对的方式执行覆盖和追加(同名跳过)操作,实现深度合并。
Parameters:
Name | Type | Default | Description |
---|---|---|---|
target |
Object | 拷贝目标(副作用修改) |
|
source |
Object | 拷贝源 |
|
mode |
Number |
0
|
模式参数,用于不同的模式:0 = 默认,1 = 深度覆盖,2 = 深度追加 |
Returns:
合并好的JavaScript对象Object
- Type
- Object
(static) clone(input) → {any}
「标准」Ux.clone
该函数是一个高频使用函数,内置使用Immutable
的API实现对象拷贝,拷贝对象分为以下几种场景:
- 普通JS对象:Object/Array,直接调用
Immutable.fromJS.toJS
的链式调用实现对象拷贝。 - DataArray/DataObject:将这两种对象的内部内容拷贝出来,生成Object或Array。
- Function:(不拷贝),直接返回原始函数,防止函数拷贝过程中的错误信息。
- NodeList:Dom对象由于挂载在HTML元素中,所以不执行拷贝,而是直接返回该Dom引用。
- Set:如果是集合,则创建一个新的集合,将元素依次追加到集合中。
- Acl数组:对存在权限控制的Array/Object而言,它会包含一个索引之外的
__acl
属性,该属性存储了Acl的权限属性。- 对Object类型而言,会直接拷贝__acl属性。
- 对Array类型,需要独立拷贝__acl属性(Immutable不会复制非索引访问的属性)。
此处的JS应用了原型链,由于Array本身是一个Object,所以除了索引以外,可直接追加属性,只是这些属性不作为标准Array元素对待。
// 直接拷贝对象,拷贝过后的对象的任何更改都不会反应到原始对象
const before = {
name: "Lang"
};
const after = Ux.clone(before);
after.name = "Lang2";
console.info(item,input);
// before 的值依旧是:{ name: "Lang" }
// after 的值为修改后的值 { name: "Lang2" };
Parameters:
Name | Type | Description |
---|---|---|
input |
DataObject | DataArray | Object | Array | 传入合法对象, |
Returns:
返回拷贝好的 Object
- Type
- any
(static) connectId(id)
「标准」Ux.connectId
必须在
componentDidMount
之后才能执行。
使用外围的代码触发onClick
操作,点击id
相匹配的元素。
Parameters:
Name | Type | Description |
---|---|---|
id |
String | 触发id的点击事件。 |
(static) element(id) → {HTMLElement}
「标准」Ux.element
等价于 document.getElementById 读取HTML元素。
Parameters:
Name | Type | Description |
---|---|---|
id |
String | HTML元素的ID值 |
Returns:
- Type
- HTMLElement
(static) immutable(input) → {Map|List}
「标准」Ux.immutable
直接调用 immutable
包中的 Immutable.fromJS 函数,生成 Immutable 对象,该对象包含了很多新的API,如常用的:
getIn
:可直接使用getIn(["field1","field11"])
读取嵌套属性。setIn
:可使用setIn(["field1","field11"])
设置嵌套属性。contains
:高频使用方法,特别是Array模式,当然也可以直接使用ES6中的Set.has
来判断。
const item = ["key", "key1"];
const $item = Ux.immutable(item);
console.info($item.contains("key"));
Parameters:
Name | Type | Description |
---|---|---|
input |
Object | Array | 输入对象,可以是任意 JavaScript 对象 |
Returns:
Immutable库中需要使用的专用对象
- Type
- Map | List
(async, static) parallel(promises, keys) → {Promise.<T>}
「标准」Ux.parallel
并行 Promise 专用函数,每个 Promise 会同时执行最终合并结果,直接构造并行运行结果
- 如果不传第二参数,keys 长度为 0,则直接返回
[x]
的 promises 直接结果 - 如果传入第二参,keys 长度 > 0,则会返回
{}
的 promises 直接结果
直接并行 []
const promiseArray = [
promise1, // 假设返回 {name:"Lang"}
promise2, // 假设返回 [1,2]
promise3 // 假设返回 "3 Promise"
];
Ux.parallel(promiseArray).then(response => {
// response 数据结构:
// [
// {name, "Lang"},
// [1,2],
// "3 Promise"
// ]
});
异构并行 {}
const promiseArray = [
promise1, // 假设返回 {name:"Lang"}
promise2, // 假设返回 [1,2]
promise3 // 假设返回 "3 Promise"
];
Ux.parallel(promiseArray, "user", "number").then(response => {
// response 数据结构:
// {
// "user": {name, "Lang"},
// "number": [1,2],
// "2": "3 Promise"
// }
});
Parameters:
Name | Type | Description |
---|---|---|
promises |
Array | 一个 Promise 的数组。 |
keys |
Array.<String> | 一个包含键的数组,用于处理最终返回值专用。 |
Returns:
返回最终的 Promise
- Type
- Promise.<T>
(async, static) pass(executor, response) → {Promise.<Any>}
「标准」Ux.pass
基本介绍
函数异步返回安全处理,直接执行 executor 函数,根据其返回值做选择:
- 如果
executor
不是一个函数,则直接返回 promise(response) 封装 - 如果
executor
是一个执行函数,则直接计算此函数,并根据返回值判断- 若返回值是一个 Promise,则直接返回
- 若返回值不是一个 Promise,则返回 promise(response)
Parameters:
Name | Type | Description |
---|---|---|
executor |
function | 传入的函数执行器 |
response |
Any | 默认返回值 |
Returns:
- Type
- Promise.<Any>
(async, static) passion(generator, input) → {Promise.<T>}
「标准」Ux.passion
顺序链接 Promise 专用函数(串行Promise),最终构造成 Monad 链
input -> Monad1 -> out1,
out1 -> Monad2 -> out2,
out2 -> Monad3 -> out3,
....
# 最终构造链式结构
Monad1 -> Monad2 -> Monad3 -> ... -> Monadn
执行步骤如下:
- 数组中的每一个元素都必须是一个函数生成器(generator),每调用一次会生成这个节点的 Promise
- 使用 generator 的目的是保证每个 Promise 都是延迟生成。
- 按照流程,第一个 generator 生成了 Promise 过后,会使用 then 的方式继续往下直到最后一个执行完成。
Parameters:
Name | Type | Description |
---|---|---|
generator |
Array | 构造每一个节点的 Promise 的专用函数 |
input |
any | 第一个节点的 Promise 的输入参数 |
Returns:
返回最终的 Promise 信息
- Type
- Promise.<T>
(static) pipe(argumentsopt)
「引擎」Ux.pipe
输入可变长度参数相关信息,暂时支持:
- 长度为1:必须输入
reference
(React中的Component)
该方法主要位于 then
的函数链执行,执行过后会更新 React 组件中的状态,该方法有一定的副作用,因为它会执行一次setState
,
所以真正使用这个函数时通常放在整个链式结构的尾部,而尾部执行操作可让系统处于最终的加载完成的状态。
【巧】技巧代码
旧代码
const reference = "从外置传入的 reference ";
Ux.ajaxGet("/api/pipe").then(state => {
reference.setState(state);
return Ux.promise(state);
});
新代码
// 使用 pipe 过后的改动代码
const reference = "从外置传入的 reference ";
Ux.ajaxGet("/api/pipe").then(Ux.pipe(reference));
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
arguments |
arguments |
<optional> |
可变长度参数 |
(static) pipeOr()
「引擎」Ux.pipeOr
(static) prevent(event) → {Object}
「标准」Ux.prevent
特殊二义性函数「Ambiguity」,该函数的输入会有两种类型,其实第一种方式应用特别多:
- 如果传入的是HTML中的
native
本地函数,通常在Button
的onClick中会被传入。 - 如果传入的是Object数据,那么直接返回该Object数据。
这个函数读取数据有另外的一个API来实现ambEvent
,所以这里只是为了执行单纯的方法,它执行的核心代码为event.preventDefault()
。
// 绑定事件
const onClick = (event) => {
Ux.prevent(event);
}
// 直接传入参数
const onForm = (params = {}) => {
const request = Ux.prevent(params);
}
Parameters:
Name | Type | Description |
---|---|---|
event |
Event | Object | 传入事件或对象 |
Returns:
返回对象信息
- Type
- Object
(async, static) promise(argumentsopt) → {Promise.<T>}
「标准」Ux.promise
多义性方法,用于返回不同结果的 Promise,多用于函数链中,该方法只对 1,2,3 的长度有效,
不在这个长度范围内时会直接返回 Promise.reject
的异常信息。
- 长度为
1
,直接返回new Promise
,将传入对象封装成 Promise 返回,同步转异步。 - 长度为
2
,使用 Supplier 和第二参直接生成 Promise 返回(延迟异步,同步转异步)。 - 长度为
3
,一般用于 Monad 函数链,通常在状态迁移中处理。
长度1
const user = {
username: "Lang Yu"
};
const promise = Ux.promise(user);
长度2
const supplier = (params = {}) => {
// 构造新的 Promise
return Ux.ajaxGet("/api/test/:key", params);
};
const promise = Ux.promise(supplier, {key:"user.id"});
长度3
【巧】技巧代码
旧代码
const state = {};
Ux.ajaxGet("/api/test").then(response => {
state.$data = response;
return Ux.promise(state);
})
新代码
const state = {};
Ux.ajaxGet("/api/test")
.then(response => Ux.promise(state, "$data", response));
使用场景分析
该API提供的方法在整个Promise链中为高频使用方法,他的使用场景有很多,主要是用于修正代码编写风格,使用场景如下:
- 直接将一个对象Object/Array等转换成带有异步Promise的数据结构,可直接调用
.then
的API。 - 长度2的使用场景主要用于切面AOP的编程,通常在很多场景中需要执行多维度构造,特别是中间维度的Promise的构造过程。
- 长度3的使用场景则通常用于
componentDidMount
的生命周期中,用于实现挂载流程,如response -> state[key] = response
的结构。
该方法存在的意义在于封装了ES6中出现的Promise流程,方便整体调用,Zero Ui的理念是封装第三方,那么第三方的内容封装越多,开发人 员对本身框架的操作程度会越过,其实第一种应用是最常用的,其次是配置化流程中通常使用第二和第三种流程。
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
arguments |
arguments |
<optional> |
可变长度参数 |
Returns:
返回最终的 Promise
- Type
- Promise.<T>
(async, static) ready(state) → {Promise.<T>}
「引擎」Ux.ready
在 Zero Extension 中,内置了配置准备状态,state 中的 $ready,当界面 componentDidMount 执行完成后 会将 $ready 设置成 true,该函数几乎是整个Zero Ui的核心,主要用于设置生命周期的完整。
- $ready = false:等待配置完成。
- $ready = true:配置执行完成,执行过程可以是异步
旧代码
const key = "1";
Ux.ajaxGet("/api/user",key).then(state => {
state.$ready = true;
return Ux.promise(state);
});
新代码
// 使用 ready 过后的改动代码
const key = "1";
Ux.ajaxGet("/api/user",key).then(Ux.ready);
该方法只能作为Monad
的中间节点,不可用于尾部节点或开始节点,只能处于函数链的中间环节,Zero中常用的一段代码如:
// 下边代码是常用代码,可设置 $ready = true 来实现准备完成
<Promise>.then(Ux.ready).then(Ux.pipe(this));
在React组件的生命周期中,componentDidMount会执行Ajax的异步操作,到最后设置
$ready=true
的标识来表示回调 完成,而这种回调完成刚好可应用于当前组件,也就是说当$ready=true
时,状态加载彻底完成。
Parameters:
Name | Type | Description |
---|---|---|
state |
处理之前的原始状态信息,函数链上的 Monad |
Returns:
返回一个新的 Promise
- Type
- Promise.<T>
(static) remove(item, keys)
「标准」Ux.remove
从 item 对象删除某些 keys 值
Parameters:
Name | Type | Description |
---|---|---|
item |
Object | 输入对象 |
keys |
String | Array | 二义性Array |