针对模块化之seaJs学习和使用和seajs源码这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Cesium中Scene模块学习和使用、Java8新特性Stream的学习和使用方法、Java
针对模块化之seaJs学习和使用和seajs源码这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Cesium中Scene模块学习和使用、Java8 新特性 Stream 的学习和使用方法、JavaScript模块化开发之SeaJS、JavaScript模块化开发之SeaJS_javascript技巧等相关知识,希望可以帮助到你。
本文目录一览:- 模块化之seaJs学习和使用(seajs源码)
- Cesium中Scene模块学习和使用
- Java8 新特性 Stream 的学习和使用方法
- JavaScript模块化开发之SeaJS
- JavaScript模块化开发之SeaJS_javascript技巧
模块化之seaJs学习和使用(seajs源码)
使用seaJs也有一阵子了,一直也想抽个时间写个这方面的博客,直到今天才写……也许写的不是很完善,但跟大伙分享也是一种乐趣,不对之处欢迎指出。[抱拳]
时间有限,我这里不过多介绍前端模块化,有兴趣可以去了解。
一、写在前面
seaJs出自前端工程师玉伯之手,一个文件就是一个模块,实现JavaScript的模块化及按模块加载。使用SeaJS可以提高JavaScript代码的可读性和清晰度,确保各个JS文件先后加载的顺序,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便代码的编写和维护。seaJs遵循的是CMD规范,所以引用一些遵循AMD规范的JS代码,需要进行一些封装处理。譬如常用的JQ就遵循的AMD规范,引用时需要做一些封装:
define(function(){
//jquery源代码
return $.noConflict();
});
seaJs浏览器兼容上理论兼容所有的浏览器,包括移动端,所以兼容性很好。同时,API少加上配置简洁清晰,学习成本较低。
二、seaJs的使用
1、模块定义。
define(function(require,exports, module){
require
是可以把其他模块导入进来的一个参数,而
exports
是可以把模块内的一些属性和方法导出的,
module
是一个对象,上面存储了与当前模块相关联的一些属性和方法。
module.exports = variable;
,一个模块要引用其他模块暴露的变量,用
var ref = require(''module_name'');
就拿到了引用模块的变量。
来一个最简单的例子。创建学习项目,相关文件及路劲如下:
index.html如下:
<!DOCTYPE html>
<html>
<head>
<title>seaJs学习 --by WZQ</title>
</head>
<body>
<script src="js/sea.js"></script>
<script>
seajs.use(''./js/index.js'');
</script>
</body>
</html>
index.js如下:
define(function(require,exports, module){
alert(1);
});
打开index.html,能执行弹出alert框,就说明引用seajs成功
接着说一下sea.config相关方面的配置。
新建一个seajs.config.js
seajs.config({
// 指定base目录
base: ''./js'',
// 目录长的可以声明别名, 这点十分人性化
alias: {
index: index.js // 左边index是别名,可以直接使用,右边是路径,由于base的存在,只需要雪名称即可,同时.js是可以去掉的
},
// 其他配置自行百度,重点是路径的配置
charset: ''utf-8'',
timeout: 20000,
debug: 0 ,
preload: ["jquery"]
});
有了配置文件,就方便管理全部的js文件,使用别名,还可以不用担心路劲问题,以后搬运js文件的时候也只需要改配置文件就好了。所以引用的时候使用别名,可以这样写:
seajs.use(''index'');(注意引入配置js)
接着练习一个复杂点的例子:
目录结构:
配置文件seajs.config.js给他们的别名如下:
seajs.config({
// 指定base目录
base: ''./js'',
// 目录长的可以声明别名, 这点十分人性化
alias: {
''index'': ''index.js'', // 左边index是别名,可以直接使用,右边是路径,由于base的存在,只需要雪名称即可,同时.js是可以去掉的
''otherJs'': ''a'',
''bJs'':''b'',
''jquery'': ''jquery.js''
},
// 其他配置自行百度,重点是路径的配置
charset: ''utf-8'',
timeout: 20000,
debug: 0 ,
preload: ["jquery"]
});
各个JS文件如下:
index.js
define(function(require,exports, module){
function Example(){
this.people = ''WZQ'';
this.address = ''广州'';
}
Example.prototype.initFn = function(){
console.log(this.people + ''在'' + this.address);
}
module.exports = Example;
});
a.js
define(function(require,exports, module){
function Other(){
this.nowTime = ''2018年10月10日''
}
module.exports = Other;
});
b.js
define(function(require,exports, module){
var $ = require(''jquery''),
AObj = require(''otherJs'');
var aObj = new AObj();
function TestObj(){
this.time = aObj.nowTime;
}
TestObj.prototype.getTime = function(){
return this.time;
}
var testObj = new TestObj();
var indexFn = {
init: function(){
var time = testObj.getTime();
console.log(''这是b.js打印出来的时间:''+ time);
$(''body'').css(''background'', ''red'');
}
}
indexFn.init();
});
index.html
<!DOCTYPE html>
<html>
<head>
<title>seaJs学习 --by WZQ</title>
</head>
<body>
<script src="js/sea.js"></script>
<script src="js/seajs.config.js"></script>
<script>
seajs.use([''index'', ''otherJs'', ''jquery'', ''bJs''], function(Example, Other, $){
var example = new Example();
example.initFn();
var other = new Other();
console.log(''今天是'' + other.nowTime);
console.log($(''body'').length); //引入jquery之后能直接用$是因为对JQ做了CMD封装,最后一行代码return $.noConflict();的缘故
});
</script>
</body>
</html>
然后最后运行结果如下即可:
Cesium中Scene模块学习和使用
Scene是Cesium中比较重要的模块之一,因为学习Cesium初期,部分api还没使用到,我就从实用性的角度,将我实战中所用到的相关api进行分析,并逐步进行补充。
设置地球模型底图颜色和场景的背景颜色
通过scene可以找到globe球体的属性,并通过globe的baseColor属性修改地球模型底图的颜色。
const viewer = new Viewer(''cesiumContainer'')
const scene = viewer.scene
scene.globe.baseColor = Cesium.Color.BLACK
设置场景背景颜色,可以先通过scene.skybox隐藏星空盒子背景,然后通过scene.backgroundColor修改背景颜色。
scene.skybox = false
scene.backgroundColor = Cesium.Color.CORNFLOWERBLUE
通过鼠标事件获取场景中某个坐标或者某个实例数据
我在实现鼠标事件交互时,会获取地图中的坐标或者想通过点击某个实例点来获取它的id,这个时候就需要通过scene.pick(position)方法来获取相关数据。
这里handler是Cesium的一个事件监听实例,callback是一个回调函数,这是一个单击事件,具体我们看一下,通过鼠标点击地图中的某一实例点,可以获取到对应的坐标position,通过scene.pick()接收一个坐标数据,则会返回实例点的具体数据(pickedObject)。
const normalEvent = {
click: function(handler, callback) {
handler.setInputAction( movement => {
const position = movement.position
const pickedObject = viewer.scene.pick(position)
callback(pickedObject, position)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
},
dbclick:...
}
性能提高
在初期学习时,我构建的地图实例的帧数感人,特别是在大量数据加载时,Cesium给出了一个提高性能的方案,提供了scene.requestRenderMode接口,该属性接收一个布尔值,如果设置为true,则只会在指定情况下进行渲染。这些环境包括:
- 通过Cesium的摄像模块api修改视图位置或方向。
- 仿真时间超过了指定的阈值。
- 加载在地形,图像,3D瓷砖,或数据源,包括每个单独的瓷砖加载。在较低的级别,当通过URI或blob解析web请求或从web工作者返回异步流程时,将触发此操作。
- 添加、删除或更改全球图像层。
- 地理高程模型改变。
- 场景模式变化。
- 框架是用Cesium API显式呈现的。
除开上述情况,其它通过Cesium API执行的操作不会主动进行渲染,也可以理解为只监听上述情况对应的API进行渲染。这样在空闲状态下,CPU的利用率会大大降低,提高性能。
配置scene.requestRenderMode属性方法:
// new Viwer实例时进行配置
const viewer = new Cesium.Viewer(''cesiumContainer'', {
requestRenderMode : true
});
// 或者new了Viewer实例之后配置
const viewer = new Cesium.Viewer(''cesiumContainer'')
viewer.scene.requestRenderMode = true
那如果我们希望使用上述场景以外的某个API时也进行渲染,应该怎么办呢,Cesium提供了scene.requestRender()方法手动渲染,如在隐藏星空背景后,执行一次scene.requestRender()方法进行渲染。
// Hides the stars
scene.skyBox.show = false
// Explicitly render a new frame
scene.requestRender()
还有一种情况,如果场景中有随时间变化的元素,比如动画、灯光变化、水面罩或视频,就要考虑到设置多少秒渲染一次,以提高性能。因为如果有动态元素,在默认情况下,会0.0秒进行一次渲染。Cesium提供了scene.maximumRenderTimeChange API,接收Number类型数据,设置多少秒后请求一个新帧。
const viewer = new Cesium.Viewer(''cesiumContainer'', {
requestRenderMode : true,
maximumRenderTimeChange : 0.5
})
如果没有随时间变化的元素,则可将maximumRenderTimeChange设置为无穷大
var viewer = new Cesium.Viewer(''cesiumContainer'', {
requestRenderMode : true,
maximumRenderTimeChange : Infinity
})
性能优化参考网站:Improving Performance with Explicit Rendering
如发现我有理解错误的请指教。
Java8 新特性 Stream 的学习和使用方法
流(Stream)
流是 java 8 中新引入的特性,用来处理集合中的数据,Stream 是一个来自数据源的元素队列并支持聚合操作。
- Java 中 Stream 不会存储元素。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器 generator 等。
- 聚合操作 类似 SQL 语句一样的操作, 比如 filter, map, reduce, find, match, sorted 等。
Stream 操作还有几个特征:
- 只遍历一次。我们可以把流想象成一条流水线,流水线的源头是我们的数据源 (一个集合),数据源中的元素依次被输送到流水线上,我们可以在流水线上对元素进行各种操作。一旦元素走到了流水线的另一头,那么这些元素就被 “消费掉了”,我们无法再对这个流进行操作。当然,我们可以从数据源那里再获得一个新的流重新遍历一遍。
- Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行 (laziness) 和短路 ( short-circuiting)。
- 内部迭代: 以前对集合遍历都是通过 Iterator 或者 For-Each 的方式,显式的在集合外部进行迭代, 这叫做外部迭代。 Stream 提供了内部迭代的方式, 通过访问者模式 (Visitor) 实现。
流的使用
流的使用过程有三步:
- 获取流;
- 中间操作,得到一个新的流;
- 最终操作,获取结果。
获取流
流有两种:
- stream () : 创建串行流。
- parallelStream () : 创建并行流。
并行流的特点就是将一个大任务切分成多个小任务,无序一起执行,当然如果我们需要顺序输出的话可以使用 forEachOrdered
,速度会比串行流快一些。它通过默认的 ForkJoinPool, 可能提高你的多线程任务的速度。
从集合获取流
List<FarmEntity> list = service.getBySql(sql1);
Stream<FarmEntity> stream = list.stream();
从数组获取流
String[] arrays = {"你", "我", "她"};
Stream<String> stream = Arrays.stream(arrays);
从值获取流
Stream<String> stream = Stream.of("你", "我", "她");
从文件获取流
try {
Stream<String> file =Files.lines(Paths.get("D:\\zhangkai\\WorkSpace\\Git\\hexo\\_config.yml"));
file.forEach(System.out::println);
} catch (Exception e) {
}
使用 NIO 获取流,可以打印出文本文件的内容。
流的操作
filter 过滤
filter 函数接收一个 Lambda 表达式作为参数,该表达式返回 boolean,在执行过程中,流将元素逐一输送给 filter,并筛选出执行结果为 true 的元素。
String[] strings = {"珊瑚", "阳光", "细腻", "冷暖", "阳光"};
Arrays.stream(strings).filter(n -> n.startsWith("冷")).forEach(System.out::print);
distinct 去重
Arrays.stream(strings).distinct().forEach(System.out::print);
limit 截取
截取前面两个单位:
Arrays.stream(strings).limit(2).forEach(System.out::print);
skip 跳过
和上面的 limit 相反,跳过前面两个
map 映射
map 方法用于映射每个元素到对应的结果。 给每个词语后面加个 “兮”
Arrays.stream(strings).map(s -> s + "兮").forEach(System.out::println);
输出:
珊瑚兮
阳光兮
细腻兮
冷暖兮
阳光兮
sorted 排序
//Arrays.stream(strings).sorted((x, y) -> x.compareTo(y)).forEach(System.out::println);
Arrays.stream(strings).sorted(String::compareTo).forEach(System.out::println);
输出:
冷暖
珊瑚
细腻
阳光
阳光
java8 以前排序:
// Before Java 8 sorted
System.out.println("java8以前排序:");
List<String> list1 = Arrays.asList(strings);
list1.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
System.out.printf("java8 以前的排序:%s%n", list1);
输出:
java8以前排序:
java8 以前的排序:[冷暖, 珊瑚, 细腻, 阳光, 阳光]
HashMap 根据 value 值排序 key:
Map<String, Integer> map = new HashMap<>();
map.put("spring", 1);
map.put("summer", 2);
map.put("autumn", 3);
map.put("winter", 4);
map.entrySet().stream()
.sorted((a, b) -> b.getValue().compareTo(a.getValue()))
.forEach(a -> System.out.println(a.getKey()));
输出结果:
winter
autumn
summer
spring
统计
//统计
List<Integer> list4 = Arrays.asList(1, 2, 3, 4, 1);
IntSummaryStatistics stats = list4.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest number in List : " + stats.getMax());
System.out.println("Lowest number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());
运行结果:
Highest number in List : 4
Lowest number in List : 1
Sum of all numbers : 11
Average of all numbers : 2.2
match 匹配
anyMatch
用于判断流中是否存在至少一个元素满足指定的条件,这个判断条件通过 Lambda 表达式传递给 anyMatch,执行结果为boolean
类型。noneMatch
与 allMatch 恰恰相反,它用于判断流中的所有元素是否都不满足指定条件findAny
能够从流中随便选一个元素出来,它返回一个 Optional 类型的元素。
Boolean result1 = Arrays.stream(strings).allMatch(s -> s.equals("java"));
System.out.println(result1);
Boolean reslut2 = Arrays.stream(strings).noneMatch(s -> s.equals("java"));
System.out.println(reslut2);
//随机读取一个
Optional<String> getResult = Arrays.stream(strings).findAny();
System.out.println(getResult);
System.out.printf("获取Optional中的值:%s%n", getResult.get());
运行结果:
false
true
Optional[冷暖]
获取Optional中的值:冷暖
Optional 是 Java8 新加入的一个容器,这个容器只存 1 个或 0 个元素,它用于防止出现 NullpointException,它提供如下方法:
isPresent()
判断容器中是否有值。ifPresent(Consume lambda)
容器若不为空则执行括号中的 Lambda 表达式。T get()
获取容器中的元素,若容器为空则抛出 NoSuchElement 异常。T orElse(T other)
获取容器中的元素,若容器为空则返回括号中的默认值。
reduce 归约
求和:
//归约
//第一种方法求和
String connectStrings = Arrays.stream(strings).reduce("", (x, y) -> x + y);
System.out.println(connectStrings);
// 第二种方法求和
String connectStrings1 = Arrays.stream(strings).reduce("", TestStream::getConnectStrings);
System.out.println(connectStrings1);
getConnectStrings 方法:
/**
* Connect Strings
* @param s1 参数1
* @param s2 参数2
* @return java.lang.String
*/
private static String getConnectStrings(String s1, String s2) {
return s1 + s2;
}
reduce
中第一个参数是初始值,第二个参数是方法引用。
数据流
StreamAPI 提供了三种数值流:IntStream、DoubleStream、LongStream,也提供了将普通流转换成数值流的三种方法:mapToInt、mapToDouble、mapToLong。
每种数值流都提供了数值计算函数,如 max、min、sum 等。
下面使用 mapToInt 为例:
String[] numberStrings = {"1", "2", "3"};
// mapToInt参数: 需要转换成相应的类型方法
IntStream intStream = Arrays.stream(numberStrings).mapToInt(Integer::valueOf);
//使用对应的 Optional 接收
OptionalInt optionalNumber = intStream.max();
// 取值,给默认值 0,为空结果为0
System.out.printf("numberStrings''s max number is: %s%n", optionalNumber.orElse(0));
打印结果:
numberStrings''s max number is: 3
由于数值流可能为空,并且给空的数值流计算最大值是没有意义的,因此 max 函数返回 OptionalInt,它是 Optional 的一个子类,能够判断流是否为空,并对流为空的情况作相应的处理。 所以可以直接使用 OptionalInt.getAsInt()
获取容器的值。
为空的话捕捉异常:
java.util.NoSuchElementException: No value present
at java.util.OptionalInt.getAsInt(OptionalInt.java:118)
at com.wuwii.test.TestStream.main(TestStream.java:105)
此外,mapToInt、mapToDouble、mapToLong 进行数值操作后的返回结果分别为:OptionalInt、OptionalDouble、OptionalLong。
Collectors 集合归约
将流转换成集合和聚合元素。
//Collectors 集合归约
// toList
List<String> list2 = Arrays.stream(strings).collect(Collectors.toList());
// Get String by connected
String connectStrings2 = Arrays.stream(strings).collect(Collectors.joining(","));
System.out.printf("Collectors toList: %s , Conlletors Join Strings: %s%n", list2, connectStrings2);
打印结果:
Collectors toList: [冷暖, 珊瑚, 细腻, 阳光, 阳光] , Conlletors Join Strings: 冷暖,珊瑚,细腻,阳光,阳光
后面补充: Collectors 中还有一个 groupingBy () 方法,比较实用,例子来源网上 < a rel="external nofollow" target="_blank" href="https://nkcoder.github.io/2016/01/24/java-8-stream-api/"> 使用 Java 8 中的 Stream</a>
groupingBy()
表示根据某一个字段或条件进行分组,返回一个Map
,其中 key 为分组的字段或条件,value 默认为 list,groupingByConcurrent()
是其并发版本:
Map<String, List<Locale>> countryToLocaleList = Stream.of(Locale.getAvailableLocales())
.collect(Collectors.groupingBy(l -> l.getDisplayCountry()));
- 如果
groupingBy()
分组的依据是一个 bool 条件,则 key 的值为 true/false,此时与 partitioningBy () 等价,且partitioningBy()
的效率更高:
// predicate
Map<Boolean, List<Locale>> englishAndOtherLocales = Stream.of(Locale.getAvailableLocales())
.collect(Collectors.groupingBy(l -> l.getDisplayLanguage().equalsIgnoreCase("English")));
// partitioningBy
Map<Boolean, List<Locale>> englishAndOtherLocales2 = Stream.of(Locale.getAvailableLocales())
.collect(Collectors.partitioningBy(l -> l.getDisplayLanguage().equalsIgnoreCase("English")));
groupingBy()
提供第二个参数,表示 downstream,即对分组后的 value 作进一步的处理:
// 返回set,而不是list:
Map<String, Set<Locale>> countryToLocaleSet = Stream.of(Locale.getAvailableLocales())
.collect(Collectors.groupingBy(l -> l.getDisplayCountry(), Collectors.toSet()));
// 返回value集合中元素的数量:
Map<String, Long> countryToLocaleCounts = Stream.of(Locale.getAvailableLocales())
.collect(Collectors.groupingBy(l -> l.getDisplayCountry(), Collectors.counting()));
// 对value集合中的元素求和:
Map<String, Integer> cityToPopulationSum = Stream.of(cities)
.collect(Collectors.groupingBy(City::getName, Collectors.summingInt(City::getPopulation)));
// 对value的某一个字段求最大值,注意value是Optional的:
Map<String, Optional<City>> cityToPopulationMax = Stream.of(cities)
.collect(Collectors.groupingBy(City::getName,
Collectors.maxBy(Comparator.comparing(City::getPopulation))));
// 使用mapping对value的字段进行map处理:
Map<String, Optional<String>> stateToNameMax = Stream.of(cities)
.collect(Collectors.groupingBy(City::getState, Collectors.mapping(City::getName,
Collectors.maxBy(Comparator.comparing(String::length)))));
Map<String, Set<String>> stateToNameSet = Stream.of(cities)
.collect(Collectors.groupingBy(City::getState,
Collectors.mapping(City::getName, Collectors.toSet())));
// 通过summarizingXXX获取统计结果:
Map<String, IntSummaryStatistics> stateToPopulationSummary = Stream.of(cities)
.collect(Collectors.groupingBy(City::getState, Collectors.summarizingInt(City::getPopulation)));
reducing()
// 可以对结果作更复杂的处理,但是reducing()却并不常用:
Map<String, String> stateToNameJoining = Stream.of(cities)
.collect(Collectors.groupingBy(City::getState, Collectors.reducing("", City::getName,
(s, t) -> s.length() == 0 ? t : s + ", " + t)));
// 比如上例可以通过mapping达到同样的效果:
Map<String, String> stateToNameJoining2 = Stream.of(cities)
.collect(Collectors.groupingBy(City::getState,
Collectors.mapping(City::getName, Collectors.joining(", ")
)));
完整代码
package com.wuwii.test;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class TestStream {
public static void main(String[] args) {
// Get Stream from file
System.out.println("读取文件:");
try {
Stream<String> file = Files.lines(Paths.get("D:\\zhangkai\\WorkSpace\\Git\\hexo\\_config.yml"));
file.forEach(System.out::println);
} catch (Exception e) {
}
// Get Stream by Filter
String[] strings = {"珊瑚", "阳光", "细腻", "冷暖", "阳光"};
Arrays.stream(strings).filter(n -> n.startsWith("冷")).forEach(System.out::print);
// Get Stream by Distinct
System.out.println("去重:");
Arrays.stream(strings).distinct().forEach(System.out::print);
// Get Stream by Limit
System.out.println("截取:");
Arrays.stream(strings).limit(2).forEach(System.out::print);
// Get Stream by Skip
System.out.println("跳过:");
Arrays.stream(strings).skip(2).forEach(System.out::print);
// Java 8 sorted
System.out.println("排序:");
//Arrays.stream(strings).sorted((x, y) -> x.compareTo(y)).forEach(System.out::println);
Arrays.stream(strings).sorted(String::compareTo).forEach(System.out::println);
// Before Java 8 sorted
System.out.println("java8以前排序:");
List<String> list1 = Arrays.asList(strings);
list1.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
System.out.printf("java8 以前的排序:%s%n", list1);
//Handle map
System.out.println("map 映射:");
Arrays.stream(strings).map(s -> s + "兮").forEach(System.out::println);
//Match
Boolean result1 = Arrays.stream(strings).allMatch(s -> s.equals("java"));
System.out.println(result1);
Boolean reslut2 = Arrays.stream(strings).noneMatch(s -> s.equals("java"));
System.out.println(reslut2);
//findAny to find anyone
Optional<String> getResult = Arrays.stream(strings).findAny();
System.out.println(getResult);
System.out.printf("获取Optional中的值:%s%n", getResult.get());
//统计
List<Integer> list4 = Arrays.asList(1, 2, 3, 4, 1);
IntSummaryStatistics stats = list4.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest number in List : " + stats.getMax());
System.out.println("Lowest number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());
//归约
//第一种方法求和
String connectStrings = Arrays.stream(strings).reduce("", (x, y) -> x + y);
System.out.println(connectStrings);
// 第二种方法求和
String connectStrings1 = Arrays.stream(strings).reduce("", TestStream::getConnectStrings);
System.out.println(connectStrings1);
//Collectors 集合归约
// toList
List<String> list2 = Arrays.stream(strings).collect(Collectors.toList());
// Get String by connected
String connectStrings2 = Arrays.stream(strings).collect(Collectors.joining(","));
System.out.printf("Collectors toList: %s , Conlletors Join Strings: %s%n", list2, connectStrings2);
String[] numberStrings = {"1", "2", "3"};
// mapToInt参数: 需要转换成相应的类型方法
IntStream intStream = Arrays.stream(numberStrings).mapToInt(Integer::valueOf);
//使用对应的 Optional 接收
OptionalInt optionalNumber = intStream.max();
// 取值,给默认值 0,为空结果为0
System.out.printf("numberStrings''s max number is: %s%n", optionalNumber.orElse(0));
}
/**
* 拼接字符串
*
* @param s1 参数1
* @param s2 参数2
* @return java.lang.String
*/
private static String getConnectStrings(String s1, String s2) {
return s1 + s2;
}
}
JavaScript模块化开发之SeaJS
前言
SeaJS是一个遵循Commonjs规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制。使用SeaJS可以提高JavaScript代码的可读性和清晰度,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便代码的编写和维护。
SeaJS本身遵循KISS(Keep it Simple,Stupid)理念进行开发,后续的几个版本更新也都是吵着这个方向迈进。
如何使用SeaJS
下载及安装在这里不赘述了,不了解的请查询官网。
基本开发原则 •一切皆为模块:SeaJS中的模块概念有点类似于面向对象中的类--模块可以拥有数据和方法,数据和方法可以定义为公共或私有,公共数据和方法可以供别的模块调用。
•每个模块应该都定义在一个单独的js文件中,即一个对应一个模块。
模块的定义和编写
模块定义函数define
SeaJS中使用define函数定义一个模块。define可以接收三个参数:
define可以接收的参数分别是模块ID,依赖模块数组及工厂函数。
•如果只有一个参数,则赋值给factory
•如果有两个参数,第二个赋值给factory,第一个如果是数组则赋值给deps,否则赋值给id
•如果有三个参数,则分别赋值
但是,包括SeaJS官网示例在内几乎所有用到define的地方都只传递一个工厂函数进去,类似于如下代码:
个人建议遵循SeaJS官方示例的标准,用一个参数的define定义模块。那么id和deps会怎么处理呢?
id是一个模块的标识字符串,define只有一个参数时,id会被默认赋值为此js文件的绝对路径。如example.com下的a.js文件中使用define定义模块,则这个模块的ID会赋值为 ,没有特别的必要建议不要传入id。deps一般也不需要传入,需要用到的模块用require加载即可。
工厂函数factory解析
工厂函数是模块的主体和重点。它的三个参数分别是:
•require:模块加载函数,用于记载依赖模块 •exports:接口点,将数据或方法定义在其上则将其暴露给外部调用 •module:模块的元数据
这三个参数可以根据需要选择是否需要显示指定。
module是一个对象,存储了模块的元信息,具体如下: •module.id:模块的ID •module.dependencies:一个数组,存储了此模块依赖的所有模块的ID列表。 •module.exports:与exports指向同一个对象
三种编写模块的模式
第一种是基于exports的模式:
上面是一种比较“正宗”的模块定义模式。除了讲公共数据和方法附加在exports上,也可以直接返回一个对象表示模块,如下面的代码与上面的代码功能相同:
如果模块定义没有其他代码,只返回一个对象,还可以有如下简化写法:
第三种写法对于定义纯JSON数据的模块非常合适。
根据应用场景的不同,SeaJS提供了三个载入模块的API,分别是:seajs.use,require和require.async。
seajs.use
seajs.use主要用于载入入口模块。入口模块相当于C语言的main函数,同时也是整个模块依赖树的根。seajs.use 的用法如下:
其中多模块的用法和KISSY中的模块加载方法类似,不亏是一个人写的啊!
一般seajs.use只用在页面载入入口模块,SeaJS会顺着入口模块解析所有依赖模块并将它们加载。如果入口模块只有一个,也可以通过给引入seajs的script标签加入“data-main”属性来省略seajs.use,例如一下写法:
javascript: //init.js define(function(require,module) { var $ = require('./jquery'); var data = require('./data'); var css = require('./style.css'); $('.author').html(data.author); $('.blog').attr('href',data.blog); }); //data.js define({ author: 'ZhangYang',blog: 'http://blog.codinglabs.org' }); css: .author{color:red;font-size:10pt;} .blog{font-size:10pt;}
请注意:
1.请讲jquery.js源码文件包含在seajs模块加载代码中;
2.在Sea.js < 2.3.0版本之前是可以加载css文件的,新版本中此功能移除,为了兼容考虑,加载css功能将作为一个插件存在。
使用方法
•可以在sea.js标签后引入这个插件使用 •也可以将插件代码混入sea.js当中 •和seajs-style的区别 •seajs-css是使 Sea.js 能够加载一个css文件,和link标签一样 •seajs-style是指提供一个seajs.importStyle方法用于加载一段 css 字符串
以上内容是小编给大家分享的JavaScript模块化开发之SeaJS,希望对大家学习javascript模块化开发有所帮助,谢谢大家一直以来对小编网站的支持。!
JavaScript模块化开发之SeaJS_javascript技巧
前言
SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制。使用SeaJS可以提高JavaScript代码的可读性和清晰度,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便代码的编写和维护。
SeaJS本身遵循KISS(Keep it Simple,Stupid)理念进行开发,后续的几个版本更新也都是吵着这个方向迈进。
如何使用SeaJS
下载及安装在这里不赘述了,不了解的请查询官网。
基本开发原则
•一切皆为模块:SeaJS中的模块概念有点类似于面向对象中的类--模块可以拥有数据和方法,数据和方法可以定义为公共或私有,公共数据和方法可以供别的模块调用。
•每个模块应该都定义在一个单独的js文件中,即一个对应一个模块。
模块的定义和编写
模块定义函数define
SeaJS中使用define函数定义一个模块。define可以接收三个参数:
/** * Defines a module. * @param {string=} id The module id. * @param {Array.|string=} deps The module dependencies. * @param {function()|Object} factory The module factory function. */ fn.define = function(id, deps, factory) { //code of function… }
define可以接收的参数分别是模块ID,依赖模块数组及工厂函数。
•如果只有一个参数,则赋值给factory
•如果有两个参数,第二个赋值给factory,第一个如果是数组则赋值给deps,否则赋值给id
•如果有三个参数,则分别赋值
但是,包括SeaJS官网示例在内几乎所有用到define的地方都只传递一个工厂函数进去,类似于如下代码:
define(function(require,exports,module){ //code of the module })
个人建议遵循SeaJS官方示例的标准,用一个参数的define定义模块。那么id和deps会怎么处理呢?
id是一个模块的标识字符串,define只有一个参数时,id会被默认赋值为此js文件的绝对路径。如example.com下的a.js文件中使用define定义模块,则这个模块的ID会赋值为 http://example.com/a.js ,没有特别的必要建议不要传入id。deps一般也不需要传入,需要用到的模块用require加载即可。
工厂函数factory解析
工厂函数是模块的主体和重点。它的三个参数分别是:
•require:模块加载函数,用于记载依赖模块
•exports:接口点,将数据或方法定义在其上则将其暴露给外部调用
•module:模块的元数据
这三个参数可以根据需要选择是否需要显示指定。
module是一个对象,存储了模块的元信息,具体如下:
•module.id:模块的ID
•module.dependencies:一个数组,存储了此模块依赖的所有模块的ID列表。
•module.exports:与exports指向同一个对象
三种编写模块的模式
第一种是基于exports的模式:
define(function(require,exports,module){ var a=require(''a''); var b=require(''b''); //引入模块 var data1=1; //私有数据 var fun1=function(){//私有方法 return a.run(data1); } exports.data2=2; //公有数据 exports.fun2=function(){ return ''hello''; } })
上面是一种比较“正宗”的模块定义模式。除了讲公共数据和方法附加在exports上,也可以直接返回一个对象表示模块,如下面的代码与上面的代码功能相同:
define(function(require){ var a=require(''a''); var b=require(''b''); //引入模块 var data1=1; var fun1=function(){ return a.run(data1); } return{ data2:2, fun2:function(){ return ''hello''; } } })
如果模块定义没有其他代码,只返回一个对象,还可以有如下简化写法:
define({ data2:2, fun2:function(){ return ''hello''; } })
第三种写法对于定义纯JSON数据的模块非常合适。
根据应用场景的不同,SeaJS提供了三个载入模块的API,分别是:seajs.use,require和require.async。
seajs.use
seajs.use主要用于载入入口模块。入口模块相当于C语言的main函数,同时也是整个模块依赖树的根。seajs.use
的用法如下:
//第一模式 seajs.use(''./a''); //回调模式 seajs.use(''./a'',function(a){ a.run(); }) //多模块模式 seajs.use([''./a'',''./b''],function(a,b){ a.run(); b.run(); })
其中多模块的用法和KISSY中的模块加载方法类似,不亏是一个人写的啊!
一般seajs.use只用在页面载入入口模块,seajs会顺着入口模块解析所有依赖模块并将它们加载。如果入口模块只有一个,也可以通过给引入seajs的script标签加入“data-main”属性来省略seajs.use,例如一下写法:
<!DOCTYPE HTML> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>TinyApp</title> </head> <body> <p></p> <script src="./sea.js" data-main="./init"></script> </body> </html> require
require是seajs主要的模块加载方法,当在一个模块中需要用到其他模块时一般用require加载:
var m=require(''./a''); require.async
上文说过seajs会在html页面打开时通过静态分析一次性记载所有需要的js文件,如果想要某个js文件在用时才加载,可以使用require.async。
这样只有在用到这个模块时,对应的js文件才会被下载,也就实现了JavaScript代码的按需加载。
SeaJS的全局配置
seajs提供了一个seaj.configd的方法可以设置全局配置,接收一个表示全局配置的配置对象,具体方法如下:
seajs.config({ base:''path'', alias:{ ''app'':''path/app/'' }, charset:''utf-8'', timeout:20000, debug:false })
其中,
•base表示基址路径
•alias可以对较长的常用路径设置缩写
•charset表示下载js时script标签的charset属性。
•timeout表示下载文件的最大时长,以毫秒为单位。
Seajs如何与现有的JS库配合使用
要将现有的JS库与seajs一起使用,只需根据seajs的模块定义规则对现有库进行一个封装。例如,下面是对jQuery的封装方法:
define(function(){ /* 此处为jquery源码 */ })
一个完整的例子:
上文说了那么多,知识点比较分散,所以最后我打算用一个完整的SeaJS例子把这些知识点串起来,方便朋友们归纳回顾。这个例子包含如下文件:
•index.html 主页面
•sea.js
•jquery.js
•init.js init模块,入口模块,依赖data、jquery、style三个模块,又主页面载入
•data.js data模块,纯json数据模块
•style.css css样式表
html: <!DOCTYPE HTML> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="content"> <p></p> <p><a href="#">Blog</a></p> </div> <script src="sea.js"></script> <script> seajs.use(''init''); </script> </body> </html> javascript: //init.js define(function(require, exports, module) { var $ = require(''./jquery''); var data = require(''./data''); var css = require(''./style.css''); $(''.author'').html(data.author); $(''.blog'').attr(''href'', data.blog); }); //data.js define({ author: ''ZhangYang'', blog: ''http://blog.codinglabs.org'' }); css: .author{color:red;font-size:10pt;} .blog{font-size:10pt;}
请注意:
立即学习“Java免费学习笔记(深入)”;
1.请讲jquery.js源码文件包含在seajs模块加载代码中;
2.在Sea.js
使用方法
•可以在sea.js标签后引入这个插件使用
•也可以将插件代码混入sea.js当中
•和seajs-style的区别 •seajs-css是使 Sea.js 能够加载一个css文件,和link标签一样
•seajs-style是指提供一个seajs.importStyle方法用于加载一段 css 字符串
以上内容是小编给大家分享的JavaScript模块化开发之SeaJS,希望对大家学习javascript模块化开发有所帮助,谢谢大家一直以来对网站的支持。!
我们今天的关于模块化之seaJs学习和使用和seajs源码的分享已经告一段落,感谢您的关注,如果您想了解更多关于Cesium中Scene模块学习和使用、Java8 新特性 Stream 的学习和使用方法、JavaScript模块化开发之SeaJS、JavaScript模块化开发之SeaJS_javascript技巧的相关信息,请在本站查询。
本文标签: