只做app不做网站可以吗,德州网站开发公司,网站建设合作协议文本,网站建设项目报价单写在前面 在实际项目中#xff0c;应用往往充斥着大量的异步操作#xff0c;如ajax请求#xff0c;定时器等。一旦应用涉及异步操作#xff0c;代码便会变得复杂起来。在flux体系中#xff0c;让人困惑的往往有几点#xff1a; 异步操作应该在actions还是store中进行应用往往充斥着大量的异步操作如ajax请求定时器等。一旦应用涉及异步操作代码便会变得复杂起来。在flux体系中让人困惑的往往有几点 异步操作应该在actions还是store中进行异步操作的多个状态如pending处理中、completed成功、failed失败该如何拆解维护请求参数校验应该在actions还是store中进行校验校验的逻辑如何跟业务逻辑本身进行分离本文从简单的同步请求讲起逐个对上面3个问题进行回答。一家之言并非定则读者可自行判别。 本文适合对reflux有一定了解的读者如尚无了解可先行查看 官方文档 。本文所涉及的代码示例可在 此处下载。 Sync Action同步操作 同步操作比较简单没什么好讲的直接上代码可能更直观。 var Reflux require(reflux);var TodoActions Reflux.createActions({addTodo: {sync: true}
});var state [];
var TodoStore Reflux.createStore({listenables: [TodoActions],onAddTodo: function(text){state.push(text);this.trigger(state);},getState: function(){return state;}
});TodoStore.listen(function(state){console.log(state is: state);
});
TodoActions.addTodo(起床);
TodoActions.addTodo(吃早餐);
TodoActions.addTodo(上班); 看下运行结果 ➜ examples git:(master) ✗ node 01-sync-actions.js
state is: 起床
state is: 起床,吃早餐
state is: 起床,吃早餐,上班 Async Action在store中处理 下面是个简单的异步操作的例子。这里通过addToServer这个方法来模拟异步请求并通过isSucc字段来控制请求的状态为成功还是失败。 可以看到这里对前面例子中的state进行了一定的改造通过state.status来保存请求的状态包括 pending请求处理中completed请求处理成功failed请求处理失败var Reflux require(reflux);/*** param {String} options.text * param {Boolean} options.isSucc 是否成功* param {Function} options.callback 异步回调* param {Number} options.delay 异步延迟的时间*/
var addToServer function(options){var ret {code: 0, text: options.text, msg: 添加成功 :)};if(!options.isSucc){ret {code: -1, msg: 添加失败};}setTimeout(function(){options.callback options.callback(ret);}, options.delay);
};var TodoActions Reflux.createActions([addTodo]);var state {items: [],status:
};var TodoStore Reflux.createStore({init: function(){state.items.push(睡觉);},listenables: [TodoActions],onAddTodo: function(text, isSucc){var that this;state.status pending;that.trigger(state);addToServer({text: text,isSucc: isSucc,delay: 500,callback: function(ret){if(ret.code0){state.status success;state.items.push(text);}else{state.status error;}that.trigger(state);}});},getState: function(){return state;}
});TodoStore.listen(function(state){console.log(status is: state.status , current todos is: state.items);
});TodoActions.addTodo(起床, true);
TodoActions.addTodo(吃早餐, false);
TodoActions.addTodo(上班, true); 看下运行结果 ➜ examples git:(master) ✗ node 02-async-actions-in-store.js
status is: pending, current todos is: 睡觉
status is: pending, current todos is: 睡觉
status is: pending, current todos is: 睡觉
status is: success, current todos is: 睡觉,起床
status is: error, current todos is: 睡觉,起床
status is: success, current todos is: 睡觉,起床,上班 Async Action在store中处理 潜在的问题 首先祭出官方flux架构示意图相信大家对这张图已经很熟悉了。flux架构最大的特点就是单向数据流它的好处在于 可预测、易测试。 一旦将异步逻辑引入store单向数据流被打破应用的行为相对变得难以预测同时单元测试的难度也会有所增加。 ps在大部分情况下将异步操作放在store里简单粗暴有效反而可以节省不少代码看着也直观。究竟放在actions、store里笔者是倾向于放在actions里的读者可自行斟酌。 毕竟社区对这个事情也还在吵个不停。。。 Async 操作在actions中处理 还是前面的例子稍作改造将异步的逻辑挪到actions里二话不说上代码。 reflux是比较接地气的flux实现充分考虑到了异步操作的场景。定义action时通过asyncResult: true标识 操作是异步的。异步操作是分状态生命周期的默认的有completed、failed。可以通过children参数自定义请求状态。在store里通过类似onAddTodo、onAddTodoCompleted、onAddTodoFailed对请求的不同的状态进行处理。var Reflux require(reflux);/*** param {String} options.text * param {Boolean} options.isSucc 是否成功* param {Function} options.callback 异步回调* param {Number} options.delay 异步延迟的时间*/
var addToServer function(options){var ret {code: 0, text: options.text, msg: 添加成功 :)};if(!options.isSucc){ret {code: -1, msg: 添加失败};}setTimeout(function(){options.callback options.callback(ret);}, options.delay);
};var TodoActions Reflux.createActions({addTodo: {asyncResult: true}
});TodoActions.addTodo.listen(function(text, isSucc){var that this;addToServer({text: text,isSucc: isSucc,delay: 500,callback: function(ret){if(ret.code0){that.completed(ret);}else{that.failed(ret);}}});
});var state {items: [],status:
};var TodoStore Reflux.createStore({init: function(){state.items.push(睡觉);},listenables: [TodoActions],onAddTodo: function(text, isSucc){var that this;state.status pending;this.trigger(state);},onAddTodoCompleted: function(ret){state.status success;state.items.push(ret.text);this.trigger(state);},onAddTodoFailed: function(ret){state.status error;this.trigger(state);},getState: function(){return state;}
});TodoStore.listen(function(state){console.log(status is: state.status , current todos is: state.items);
});TodoActions.addTodo(起床, true);
TodoActions.addTodo(吃早餐, false);
TodoActions.addTodo(上班, true); 运行看程序输出 ➜ examples git:(master) ✗ node 03-async-actions-in-action.js
status is: pending, current todos is: 睡觉
status is: pending, current todos is: 睡觉
status is: pending, current todos is: 睡觉
status is: success, current todos is: 睡觉,起床
status is: error, current todos is: 睡觉,起床
status is: success, current todos is: 睡觉,起床,上班 Async Action参数校验 前面已经示范了如何在actions里进行异步请求接下来简单演示下异步请求的前置步骤参数校验。 预期中的流程是 流程1参数校验 -- 校验通过 -- 请求处理中 -- 请求处理成功失败 流程2参数校验 -- 校验不通过 -- 请求处理失败 预期之外store.onAddTodo 触发 直接对上一小节的代码进行调整。首先判断传入的text参数是否是字符串如果不是直接进入错误处理。 var Reflux require(reflux);/*** param {String} options.text * param {Boolean} options.isSucc 是否成功* param {Function} options.callback 异步回调* param {Number} options.delay 异步延迟的时间*/
var addToServer function(options){var ret {code: 0, text: options.text, msg: 添加成功 :)};if(!options.isSucc){ret {code: -1, msg: 添加失败};}setTimeout(function(){options.callback options.callback(ret);}, options.delay);
};var TodoActions Reflux.createActions({addTodo: {asyncResult: true}
});TodoActions.addTodo.listen(function(text, isSucc){var that this;if(typeof text ! string){that.failed({ret: 999, text: text, msg: 非法参数});return;}addToServer({text: text,isSucc: isSucc,delay: 500,callback: function(ret){if(ret.code0){that.completed(ret);}else{that.failed(ret);}}});
});var state {items: [],status:
};var TodoStore Reflux.createStore({init: function(){state.items.push(睡觉);},listenables: [TodoActions],onAddTodo: function(text, isSucc){var that this;state.status pending;this.trigger(state);},onAddTodoCompleted: function(ret){state.status success;state.items.push(ret.text);this.trigger(state);},onAddTodoFailed: function(ret){state.status error;this.trigger(state);},getState: function(){return state;}
});TodoStore.listen(function(state){console.log(status is: state.status , current todos is: state.items);
});// 非法参数
TodoActions.addTodo(true, true); 运行看看效果。这里发现一个问题尽管参数校验不通过但store.onAddTodo 还是被触发了于是打印出了status is: pending, current todos is: 睡觉。 而按照我们的预期store.onAddTodo是不应该触发的。 ➜ examples git:(master) ✗ node 04-invalid-params.js
status is: pending, current todos is: 睡觉
status is: error, current todos is: 睡觉 shouldEmit 阻止store.onAddTodo触发 好在reflux里也考虑到了这样的场景于是我们可以通过shouldEmit来阻止store.onAddTodo被触发。关于这个配置参数的使用可参考文档。 看修改后的代码 var Reflux require(reflux);/*** param {String} options.text * param {Boolean} options.isSucc 是否成功* param {Function} options.callback 异步回调* param {Number} options.delay 异步延迟的时间*/
var addToServer function(options){var ret {code: 0, text: options.text, msg: 添加成功 :)};if(!options.isSucc){ret {code: -1, msg: 添加失败};}setTimeout(function(){options.callback options.callback(ret);}, options.delay);
};var TodoActions Reflux.createActions({addTodo: {asyncResult: true}
});TodoActions.addTodo.shouldEmit function(text, isSucc){if(typeof text ! string){this.failed({ret: 999, text: text, msg: 非法参数});return false;}return true;
};TodoActions.addTodo.listen(function(text, isSucc){var that this;addToServer({text: text,isSucc: isSucc,delay: 500,callback: function(ret){if(ret.code0){that.completed(ret);}else{that.failed(ret);}}});
});var state {items: [],status:
};var TodoStore Reflux.createStore({init: function(){state.items.push(睡觉);},listenables: [TodoActions],onAddTodo: function(text, isSucc){var that this;state.status pending;this.trigger(state);},onAddTodoCompleted: function(ret){state.status success;state.items.push(ret.text);this.trigger(state);},onAddTodoFailed: function(ret){state.status error;this.trigger(state);},getState: function(){return state;}
});TodoStore.listen(function(state){console.log(status is: state.status , current todos is: state.items);
});// 非法参数
TodoActions.addTodo(true, true);
setTimeout(function(){TodoActions.addTodo(起床, true);
}, 100)再次运行看看效果。通过对比可以看到当shouldEmit返回false就达到了之前预期的效果。 ➜ examples git:(master) ✗ node 05-invalid-params-shouldEmit.js
status is: error, current todos is: 睡觉
status is: pending, current todos is: 睡觉
status is: success, current todos is: 睡觉,起床 写在后面 flux的实现细节存在不少争议而针对文中例子reflux的设计比较灵活同样是使用reflux也可以有多种实现方式具体全看判断取舍。 最后欢迎交流。