本文目标:但愿经过买进口水果生鲜的例子,和你们探讨一下如何处理异步的
async action
。node
在上一篇文章 Redux入门 -- 拆分 reducer 中,阿大经过 redux
的 bindReducers
方法将水果店的业务分治成功,店铺也越作越大。以致于有顾客开始想要买一些进口的水果生鲜。git
阿大考虑了一下,决定继续拓展这个店铺,从事进口商品的销售。首先是顾客的需求行为须要购买进口水果生鲜:github
// 买水果 - 进口苹果
+ function buyImportedApple(num) {
+ return {
+ type: 'BUY_IMPORTED_APPLE',
+ payload: {
+ num
+ }
+ }
+ }
// 买生鲜 - 进口鸡蛋
+ function buyImportedEgg(num) {
+ return {
+ type: 'BUY_IMPORTED_EGG',
+ payload: {
+ num
+ }
+ }
+ }
复制代码
而后水果部和生鲜部的帐本也要更新啦:redux
// 水果帐本
const fruitState = {
orange: 0,
apple: 0,
banana: 0,
+ importedApple: 0
};
// 生鲜帐本
const freshState = {
egg: 0,
fish: 0,
vegetable: 0,
+ importedEgg: 0
};
复制代码
一样的,相应部门的收银员们也要学会怎么处理进口水果生鲜的记帐,他们的记帐方式要改为下面这样:app
// 水果部收银员
function fruitReducer(state = fruitState, action) {
// 若是有人买了相应的水果,更新帐本
switch (action.type) {
case 'BUY_APPLE':
return Object.assign({}, state, {
apple: state.apple + action.payload.count
});
case 'BUY_IMPORTED_APPLE':
return Object.assign({}, state, {
importedApple: state.importedApple + action.payload.count
});
// 买其余的东西,不更新帐本,原样返回
default: return state;
}
}
// 生鲜部收银员
function freshReducer(state = freshState, action) {
switch (action.type) {
case 'BUY_EGG':
return Object.assign({}, state, {
egg: state.egg + action.payload.count
});
case 'BUY_IMPORTED_EGG':
return Object.assign({}, state, {
importedEgg: state.importedEgg + action.payload.count
});
default: return state;
}
}
复制代码
但是这时候阿大发现,进口水果生鲜不能大量存在本身仓库卖,由于它们又贵又容易坏,只有当顾客须要买的时候,才能去采购这些水果生鲜,因而阿大又雇了一个采购员专门负责处理要买进口水果和生鲜的顾客,等到货了再通知销售员取货给顾客:异步
// 采购商品生成器,不一样的商品须要不一样的时间采购
function fetchGoodsGenerator(time, action) {
// 用延时模拟采购时间
const timer = setTimeout(() => {
clearTimeout(timer);
// 采购完成,通知销售员
store.dispatch(action);
}, time);
}
// 采购进口苹果须要 2 天(2s)
function fetchImportedApple(action) {
fetchGoodsGenerator(2000, action);
}
// 采购进口鸡蛋须要 3 天(3s)
function fetchImportedEgg(action) {
fetchGoodsGenerator(3000, action);
}
// 采购员
const API = {
fetchImportedApple, // 采购进口苹果
fetchImportedEgg // 采购进口鸡蛋
}
复制代码
好了,布置完了以后,顾客开始来买水果生鲜了:async
// 销售员开始销售,采购员开始采购
store.dispatch(buyApple(3));
API.fetchImportedApple(buyImportedApple(10));
store.dispatch(buyEgg(1));
API.fetchImportedEgg(buyImportedEgg(10));
store.dispatch(buyApple(4));
API.fetchImportedApple(buyImportedApple(10));
store.dispatch(buyEgg(8));
API.fetchImportedEgg(buyImportedEgg(10));
// {"fruit":{"apple":3,"importedApple":0},"fresh":{"egg":0,"importedEgg":0}}
// {"fruit":{"apple":3,"importedApple":0},"fresh":{"egg":1,"importedEgg":0}}
// {"fruit":{"apple":7,"importedApple":0},"fresh":{"egg":1,"importedEgg":0}}
// {"fruit":{"apple":7,"importedApple":0},"fresh":{"egg":9,"importedEgg":0}}
// {"fruit":{"apple":7,"importedApple":10},"fresh":{"egg":9,"importedEgg":0}}
// {"fruit":{"apple":7,"importedApple":20},"fresh":{"egg":9,"importedEgg":0}}
// {"fruit":{"apple":7,"importedApple":20},"fresh":{"egg":9,"importedEgg":10}}
// {"fruit":{"apple":7,"importedApple":20},"fresh":{"egg":9,"importedEgg":20}}
复制代码
如今水果生鲜店的进口业务也稳妥了,阿大内心美滋滋~函数
在实际的开发当中咱们常常会调用一些 API 接口获取数据更新 state。刚开始使用 redux 的一个误区就是在 reducer 里接收到异步的 action 以后,就在 reducer 里作异步操做,调用 API。可是这样是错误的。reducer 只能是纯函数,不能有任何反作用。这样才能保证对于相同的输入,必定会有相同的输出。post
代码地址:Redux 入门 -- 处理 async action,直接控制台运行
node ./demo3/index.js
查看效果fetch