原 荐 any-loader JS数据加载器中间件
栏目: JavaScript · 发布时间: 7年前
内容简介:any-loader 旨在为 node.js 和其他的 javascript 提供一个可定制程度较高的数据加载器中间件类库。本身并不实现任何数据加载器的实现逻辑,只界定了数据 流走向的标准接口any-loader 支持并实现了以下编程特性:码云仓库地址:
简介
any-loader 旨在为 node.js 和其他的 javascript 提供一个可定制程度较高的数据加载器中间件类库。本身并不实现任何数据加载器的实现逻辑,只界定了数据 流走向的标准接口 newLoadStrem -> setup -> beforeLoad -> doLoad -> afterLoad ,调用顺序(不可逆),以及此过程中的异常错误处理机制。
any-loader 支持并实现了以下编程特性:
- 基于AOP设计,支持异步(Promise)。
- 中间件形态,不干涉业务逻辑和底层实现。
- 使用OOP进行扩展,使用继承和方法重载,来进行子类的开发,并提供丰富的方法以控制的粒度。
- 接口基于 Promise 封装,向后兼容 async/await 语法
- 数据流(LoadStream)部分,使用 fp 编程,数据流持有的
input,output等数据,只在接口中流转,结束后即作废。 Loader 本身无状态,不持有过程数据。
码云仓库地址: https://gitee.com/janpoem/any-loader
设计初衷
在决定将 any-loader 作为独立的项目前,正忙于一个基于 React.js Web 实现的后台文件管理系统,因为前端环境和服务器环境,需要在前端集成比较多的数据接口。
- 一般的 Ajax 拉取文件列表、单个文件、更新文件修改等。
- 前端的 FileReader ,识别和检测用户上传文件的安全性,以及图片和视频客户端生成预览(嗯,现在这些都转移到前端实现了,没必要交给后端做了,以后有空再把这一块开源)。
- 客户端直接上传到 CDN,没必要再从服务器走一趟了,根据文件类型,还要通知 CDN 对文件进行各种处理(如视频转码、压缩分辨率,图片生成缩略图等)。
- 上传完毕,需要更新服务器端,记录文件信息,以及有效的 CDN 资源地址。
前端需要异步调用的地方很多,最初的想法是将功能和资源点接近形成一个加载器组,进行封装管理。可是随着开发的代码增加,就越发发现加载器组控制粒度不够细。
- 随着接口越来越多,应用层面、界面层面的调用代码越来越多,越来越多的结构控制,更别提在不改变调用代码的前提下,去扩展和细化加载器的中间逻辑代码,只能不断的增加应用层的代码量。
- 异步环调用情况更恶劣。项目里有对Ajax的请求封装,但这只适合单次Ajax(适合网站前台)请求,后台的请求,特别是文件管理系统,往往在执行一个操作,往往涉及到一个系列的异步调用环。比如上传到 CDN,要先从服务器端拿到 token ,上传完毕后,还需要将信息保存到服务器端。
- 基于 JS 老掉牙的事件驱动,应用层的代码会臃肿不堪,不断嵌套的事件注册,不利于后续的扩展和开发。
- 缺乏统一调度管理,这里说的调度,即同类接口的并发策略,是等待、取消还是延后等。嗯,是的,当更大程度的使用 React.js ,对于各种数据加载,其实隐性的存在这一个并发调度管理的需求,现有的各种 工具 类库,并没有在这些方面有很好的着力点,可以说完全为零。在C#和 Java 等静态语言有线程安全一说,可是在过去20多年的JS开发中,并没有这个概念。但随着现在前端技术发展的程度,前端的异步调度安全性,成为一个非常重要的内容(特别是Web Worker、Service Worker、大量的 Promise 环境下)。
- 基于 React.js 的一些特性,想将数据加载接口传递进组件内被使用,是一个比较头疼的问题。当然可以选择使用 Redux 等,Redux 开拓了一个全新的编码区间,以解决这方面的问题。但我并不是太喜欢这种动不动就打开一个新的编码空间的做法,太多框架一再用事实告诉我们,如果不解决问题本身,而为了解决某类型问题去开拓一个新的编码区间,最终那个区间只会成为一个无王法、无规范,代码质量差,问题成堆的集中地,所以还是要回到问题本质。
经过一番思索和准备,我决定将 any-loader 作为一个独立的类库来实现。any-loader 不旨在解决实际加载器的业务流程的复杂度,也不提供 Loader 的实现,更不会考虑对任何数据加载方式做封装。any-loader 只定义了一个数据加载流的接口调用顺序,并将足够多的方法和接口进行暴露,提供给子类更多细化调节和扩展的空间。同时,在不改变应用层的调用代码的前提下,随着项目的开发程度和需求细化程度,可以逐步对项目实际的 Loader 进行渐进式的升级和扩展,而不需要一再的去调整应用层的调用代码。
简单示例
class ImageLoader extends Loader {
// 默认形态下,input, output 是 {}
doLoad({input, output, errors}) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = function(ev) {
output.image = this;
output.width = this.width;
output.height = this.height;
resolve();
};
image.onerror = (ev) => {
reject(new Error('图片加载失败!'));
};
image.src = input.url;
});
}
}
const loader = new ImageLoader();
loader.load({url: 'https://www.oschina.net/build/oschina/components/imgs/header/logo.svg'}).then(({output}) => {
}).catch(error => {
});
这里定义了一个图片加载器,通过 doLoad 方法的重载,来实现该加载器的具体实现。当然这个例子看起来很简单,市面上大把这样的图片加载器的类库。下来我们接着扩展。
// 我们先定义了一个远程的URL类,或者你的项目本身就有类似的设定
class RemoteURL {
constructor() {
// ....
}
toURL() {
return '...';
}
}
// 再定义一个远程的图片类
class RemoteImage {
constructor(remoteUrl) {
this.url = remoteUrl; // 这是一个RemoteURL的实例
this.isLoad = false;
this.image = null;
this.error = null;
}
load(image) {
this.isLoad = true;
this.image = image;
}
error(error) {
this.error = error;
}
}
class ImageLoader extends Loader {
// 我们将 RemoteURL 的实例,作为 LoadStream 的 input
newInput(input) {
return new RemoteURL(this.mergeArgs(input));
}
newOutput(input, output) {
// 到这里时,input已经变为 RemoteURL 的实例
return new RemoteImage(input);
}
// input => RemoteURL, output => RemoteImage
doLoad({input, output, errors}) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = function(ev) {
output.load(this);
resolve();
};
image.onerror = (ev) => {
output.error(new Error('图片加载失败!'));
reject(output.error);
};
image.src = input.toURL();
});
}
}
// 调用代码
const loader = new ImageLoader();
loader.load({url: 'https://www.oschina.net/build/oschina/components/imgs/header/logo.svg'}).then(({output}) => {
}).catch(error => {
});
第二个例子中,我们增加了两个中间类,以对ImageLoader 的输入、输出,进行更细的控制。同时,为ImageLoader重载了两个方法,以将输入、输出的实例绑定到ImageLoader 标准流程中去。在应用层调用的代码不变的前提下,通过增加中间层的代码,实现了对Loader更多的控制。
更多例子,后续更新
版本说明
现阶段,不考虑基于类库层面解决并发策略的问题,而在具体的项目里实现的 子类Loader 去简单的管理。
未完,待续。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Cascading Style Sheets 2.0 Programmer's Reference
Eric A. Meyer / McGraw-Hill Osborne Media / 2001-03-20 / USD 19.99
The most authoritative quick reference available for CSS programmers. This handy resource gives you programming essentials at your fingertips, including all the new tags and features in CSS 2.0. You'l......一起来看看 《Cascading Style Sheets 2.0 Programmer's Reference》 这本书的介绍吧!