在前面的章节中,我们设置了代理,于是所有的 HTTP 请求都可以先到达本地开发服务器,再被转发。在实际的开发中,后端的服务不一定马上可用,这就需要本地服务器另外一个能力:模拟数据(mock)。设置代理是 mock 的前提。
一个 ajax 请求发送到本地开发服务器后,我们可以设置:如果请求满足某个规则,则不转发这个请求,而是直接返回一个「假」结果给浏览器。在实际的开发中,我们常常先和服务端的同学商定 http 请求的接口接受什么参数,返回什么结果,然后先用 mock 数据来模拟,自己和自己「联调」。等待服务端同学开发好了,再解除 mock,用真实数据「联调」。
模拟正常返回数据
设置模拟数据时需要在工程根目录下的 mock
子目录中的建立文件。首先在工程中增加 mock 目录,并在其中创建文件 puzzlecards.js
(取其他名字也可以,名字这里不需要)。如果想 mock 掉我们在上一个章节中的向 /dev/random_joke
的 ajax 调用,需要写入以下内容到文件,
const random_jokes = [
{
setup: 'What is the object oriented way to get wealthy ?',
punchline: 'Inheritance',
},
{
setup: 'To understand what recursion is...',
punchline: "You must first understand what recursion is",
},
{
setup: 'What do you call a factory that sells passable products?',
punchline: 'A satisfactory',
},
];
let random_joke_call_count = 0;
export default {
'get /dev/random_joke': function (req, res) {
const responseObj = random_jokes[random_joke_call_count % random_jokes.length];
random_joke_call_count += 1;
setTimeout(() => {
res.json(responseObj);
}, 3000);
},
};
如果你不断地刷新页面,会发现每次拿到的数据是不同的。并且由于 setTimeout 的存在使得卡片的更新变慢了。
我们通过这个例子解释一下怎么写 mock 数据。
首先,整个文件需要 export 出一个 js 对象。对象的 key 是由
<Http_verb> <Resource_uri>
构成的,值是 function,当一个 ajax 调用匹配了 key 后,与之对应的 function 就会被执行。函数中我们调用 res.json 就可以给浏览器返回结果。函数中可以使用 setTimeout 来模拟异步调用服务时的时延。
模拟出错
利用 res.status 也可以模拟 http 请求出错。例如,我们把文件中的 export default 块替换成下面的内容,
export default {
'get /dev/random_joke': function (req, res) {
res.status(500);
res.json({});
},
};
在 dva model 中我们加入简单的错误捕获:
import { message } from 'antd';
// ... 原有逻辑不修改
try { // 加入 try catch 捕获抛错
const puzzle = yield call(request, endPointURI);
yield put({ type: 'addNewCard', payload: puzzle });
yield call(delay, 3000);
const puzzle2 = yield call(request, endPointURI);
yield put({ type: 'addNewCard', payload: puzzle2 });
} catch (e) {
message.error('数据获取失败'); // 打印错误信息
}
于是可以看到出错状况下的页面:
在每一个调用点做打印错误信息很麻烦,这里只是为了展示 mock 出错场景。在实际的开发中,一般会统一处理 http 请求错误时的信息提示。
简单数据模拟
刚才的模拟中,mock 具备动态改变、延时返回等能力,如果你不需要这个能力,也可以简单地使用对象。
export default {
'get /dev/random_joke': {
setup: 'What is the object oriented way to get wealthy ?',
punchline: 'Inheritance',
},
};