课前作业
- 如果你对 promise 、reflux 还不那么熟悉,请先行了解他们是什么,有什么用。
ReFlux细说
大白话讲解Promise
现状分析
首先我们来絮叨絮叨后端同学是怎么写代码的。
-
首先絮叨一下经典问题,MVC
- 用户看到view
- view ——————————》 controller用户操作(点击按钮等)
- controller——————》model调用model中方法
- model ——————》 controller返回数据到controller
- controller——————————》 view传数据到view,更新view
- 用户看到更新后的view M——模型层,V——视图层,C——控制层,持久层——通常用于封装数据库连接、数据查询等操作。
-
个人的理解就是这个样子。MVC是整体的设计模式,具体到实现上,还要分三层:
笔者遇到了一个逻辑超级复杂的项目,接手时代码很多很长,理解起来超级痛苦。于是便有了这样的思考,我们前端同学去写代码,能不能也效仿这三层结构呢?答案是肯定的,且听我慢慢道来。
先来个前后端分层对比
-
数据访问层 - ajax 请求
- 后端实现,写sql > 塞数据 > 得到结果
- 前端实现,写url > 传参数 > 得到结果
是不是惊人的一致呢?
-
业务逻辑层 - store
- 后端实现,按不同的需求调用不同的数据访问层方法,这里有事务的概念。
- 前端实现,按不同的需求调用不同的数据访问层方法,这里不需要事务的概念,一定要有的话,一个是后端可以帮你变没有,一个是用 Promise.all 吧。事务这个概念在前端基本不存在,或者这种情况不多,但总有变通的办法嘛~
信息资源层 - index.js
后端实现, 拿到前端传回的参数,格式化数据,调用业务逻辑层的方法。格式化结果,返回数据。
前端实现,拿到用户数据,格式化数据,调用业务逻辑层的方法,格式化结果,渲染页面。
-
前端可用资源,reflux 提供了action 和 store ,react 提供了 index.js。
- action 只是注册了 store 中的事件,哪些是暴露出来的。
- 所以,我们的数据访问层和业务逻辑层都要放在 store 中去实现。
实现
- 因为一个store要实现数据访问层和业务逻辑层两个概念,所以我们只能在写法上去做文章了。
- 数据访问层我们以下划线开头,表示私有,只有在store中可以访问,因为我们业务逻辑层也在store中,而理论上来说数据访问层只有在业务逻辑层中才会被调用,所有很完美。比如这样:
_add(){ ajax('add.json',param,callback)
}
_delete(){
ajax('delete.json',param,callback)
}
_update(){
ajax('update.json',param,callback)
}
大白话说就是把ajax请求封装了一下。
- **业务逻辑层**我们以 on 开头,表示向外暴露,并同时在action中注册。比如这样
```javascript
//store.js
onAdd(){
_add();
_update();
}
onDelete(){
_delete();
_update();
}
//*********************** 分割线 ************************
//action.js
module.exports = Reflux.createActions([
'add',
'delete'
]);
-
信息资源层就是我们的主页面了,使用很简单,比如这样
handleAdd(){ Action.add();
}
handleDelete(){
Action.delete();
}
- 通过这种方式,我们就实现了后端同学的三层架构。
## Promise 语法糖
- 在事务处理层我们避免不了要有执行顺序,比如 add 执行完后再去执行 update。传统的写法肯定就是嵌套,在 add 执行完后去执行 update。这样就会造成金字塔式的代码,让代码很难维护。Promise应运而生。
- 代码具体实现
- 数据访问层
```javascript
//_add 改造,主要是返回promise对象
_add(){
var promise = new Promise(function(resolve, reject) {
$.ajax('add',params,function(){
if(success){
//Todo...
resolve(value);
}else{
//Todo...
reject(error);
}
});
return promise;
}
//_update 改造,主要是返回promise对象
_update(){
var promise = new Promise(function(resolve, reject) {
$.ajax('update',params,function(){
if(success){
//Todo...
resolve(value);
}else{
//Todo...
reject(error);
}
});
return promise;
}
- 业务逻辑层
onAdd(){
_add.then(function(){
//_add成功回调,这个时候我们去执行_update(也是promise对象),并且把_update 返回
return _update();
},function(){
//_add失败回调 Todo...
}).then(function(){
//_update成功回调 Todo...
},function(){
//_update失败回调 Todo...
})
}
使用场景
理论上说,如果你想要自己的代码更好维护,更容易让别人看懂,都可以使用。
-
最适用的场景是层层嵌套的ajax请求,并且被嵌套的ajax请求在别的地方又被大量使用,比如:
- 打车系统的出发地/目的地改变,引起重新获取附近车辆信息,然后根据车辆信息重新获取预估价格。
场景的共性就是: 一个操作后会引起别的操作,每个操作都是有执行顺序的;而且后续的操作在别的地方又被经常调用到。
大概就是这些了,如有不当之处,还请观众老爷指出。